diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..9dfc9af --- /dev/null +++ b/.env.example @@ -0,0 +1,23 @@ +TZ=America/Chicago + +# Relative paths to the various configuration files +CONFIG_PATH=./mrefd.cfg +BLACKLIST_PATH=./mrefd.blacklist +WHITELIST_PATH=./mrefd.whitelist +INTERLINK_PATH=./mrefd.interlink +DASH_CONFIG_PATH=./php-dash/include/config.inc.php + +# Port to bind the services to on the host machine +HOST_M17_PORT=17000 +HOST_DHT_PORT=17171 +HOST_DASHBOARD_PORT=80 + +# Port to bind the services to inside the container +# These should match the ports in mrefd.cfg +CONTAINER_M17_PORT=17000 +CONTAINER_DHT_PORT=17171 +CONTAINER_DASHBOARD_PORT=80 + +# Path to where DHT file should be stored +# DHT_PATH=./mrefd.dht.bin +# TODO uncomment once this is working diff --git a/.github/workflows/publish-docker-dashboard.yaml b/.github/workflows/publish-docker-dashboard.yaml new file mode 100644 index 0000000..8f63033 --- /dev/null +++ b/.github/workflows/publish-docker-dashboard.yaml @@ -0,0 +1,63 @@ +name: Publish mrefd-dash Docker Image to GHCR + +env: + REGISTRY: ghcr.io + REGISTRY_IMAGE: ${{ github.repository_owner }}/mrefd-dash + +on: + push: + paths: + - '.github/workflows/publish-docker-dashboard.yaml' + - 'php-dash/**' + branches: + - "**" + tags: + - "v*.*.*" + pull_request: + paths: + - '.github/workflows/publish-docker-dashboard.yaml' + - 'php-dash/**' +jobs: + build-and-publish-dash: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write # Required to push to GHCR + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY}} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image for mrefd-dash + uses: docker/build-push-action@v6 + with: + context: ./php-dash + file: ./php-dash/Containerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/publish-docker.yaml b/.github/workflows/publish-docker.yaml new file mode 100644 index 0000000..f544078 --- /dev/null +++ b/.github/workflows/publish-docker.yaml @@ -0,0 +1,59 @@ +name: Publish mrefd Docker Image to GHCR + +env: + REGISTRY: ghcr.io + REGISTRY_IMAGE: ${{ github.repository_owner }}/mrefd + + +on: + push: + branches: + - "**" + tags: + - "v*.*.*" + pull_request: + +jobs: + build-and-publish-mrefd: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write # Required to push to GHCR + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY}} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.REGISTRY_IMAGE }} + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push Docker image for mrefd + uses: docker/build-push-action@v6 + with: + context: . + file: Containerfile + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..6815030 --- /dev/null +++ b/Containerfile @@ -0,0 +1,26 @@ +FROM debian:12.11-slim + +# Install dependencies +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + git build-essential g++ libcurl4-gnutls-dev libopendht-dev \ + && rm -rf /var/lib/apt/lists/* + +# Set the working directory +WORKDIR /app +# Copy project to the build context +COPY . ./ + +# Copy default config files into app dir +RUN cp config/mrefd.blacklist . \ + && cp config/mrefd.whitelist . \ + && cp config/mrefd.interlink . \ + && cp example.mk mrefd.mk \ + && cp example.cfg mrefd.cfg + +RUN make \ + && make install + +EXPOSE 17000/udp 17171/udp + +CMD [ "/usr/local/bin/mrefd", "/app/config/mrefd.cfg" ] diff --git a/Makefile b/Makefile index 21d41d3..ba30931 100644 --- a/Makefile +++ b/Makefile @@ -77,16 +77,20 @@ install : $(EXE).blacklist $(EXE).whitelist $(EXE).interlink $(EXE).cfg $(CPORLN) $(shell pwd)/$(EXE).cfg $(CFGDIR)/$(EXE).cfg sed -e "s#XXX#$(CFGDIR)#" -e "s#YYY#$(EXE)#" systemd/mrefd.service > /etc/systemd/system/$(EXE).service cp -f $(EXE) $(BINDIR) +ifeq ($(DAEMON), true) systemctl enable $(EXE).service systemctl daemon-reload systemctl start $(EXE) +endif uninstall : rm -f $(CFGDIR)/$(EXE).blacklist rm -f $(CFGDIR)/$(EXE).whitelist rm -f $(CFGDIR)/$(EXE).interlink rm -f $(CFGDIR)/$(EXE).cfg +ifeq ($(DAEMON), true) systemctl stop $(EXE).service systemctl disable $(EXE).service rm -f /etc/systemd/system/$(EXE).service systemctl daemon-reload +endif diff --git a/README.md b/README.md index d6c399f..6a80d0a 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,32 @@ The packages which are described in this document are designed to install server Below are instructions for building an mrefd reflector. +### Running with Docker + +```bash +# First, copy the configuration files to your working directory and edit them as you see fit according to the rest of the documentation +cp config/mrefd.blacklist . +cp config/mrefd.whitelist . +cp config/mrefd.interlink . +cp example.cfg mrefd.cfg +# Note: in mrefd.cfg, a few edits are expected in order to run properly in the containerized environment: +# - IPv4ExtAddr _must be set_, as the automated way of fetching the external IP does not work when in a container +# - PidPath = /app/data/mrefd.pid +# - XmlPath = /app/data/mrefd.xml +# - WhitelistPath = /app/config/mrefd.whitelist +# - BlacklistPath = /app/config/mrefd.blacklist +# - InterlinkPath = /app/config/mrefd.interlink + +cp php-dash/include/config.inc.php.dist php-dash/include/config.inc.php +# Edit the php-dash/include/config.inc.php file with your editor of choice +# Note: $PageOptions['IPV4'] needs to be set to "mrefd-mrefd" thanks to docker magic +# Note: PIDFile and XMLFile need to be set to /app/data/mrefd.pid and /app/data/mrefd.xml accordingly +# Note: comment out the date_default_timezone_set line, since we're setting timezone via env vars instead +cp .env.example .env +# Edit the .env file as you need for your deployment +docker compose up +``` + ### After a clean installation of a Debian-based OS make sure to run update and upgrade ```bash diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..32928e8 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,40 @@ + +services: + mrefd: + build: + context: . + dockerfile: Containerfile + image: mrefd:latest + container_name: mrefd + environment: + - TZ=${TZ:-America/Chicago} + volumes: + - "${CONFIG_PATH:-./mrefd.cfg}:/app/config/mrefd.cfg:ro" + - "${BLACKLIST_PATH:-./mrefd.blacklist}:/app/config/mrefd.blacklist:ro" + - "${WHITELIST_PATH:-./mrefd.whitelist}:/app/config/mrefd.whitelist:ro" + - "${INTERLINK_PATH:-./mrefd.interlink}:/app/config/mrefd.interlink:ro" + - mrefd_data:/app/data + # - "${DHT_PATH:-./mrefd.dht.bin}:/app/config/mrefd.dht.bin" # TODO: sort out how to initialize the dht bin as part of env setup before the contrainer loads; empty file results in errors + ports: + - ${HOST_M17_PORT:-17000}:${CONTAINER_M17_PORT:-17000}/udp + - ${HOST_DHT_PORT:-17171}:${CONTAINER_DHT_PORT:-17171}/udp + + restart: unless-stopped + mrefd_dashboard: + build: + context: ./php-dash + dockerfile: Containerfile + image: mrefd-dash:latest + depends_on: + - mrefd + container_name: mrefd_dashboard + environment: + - TZ=${TZ:-America/Chicago} + volumes: + - "${DASH_CONFIG_PATH:-./php-dash/include/config.inc.php}:/var/www/html/php-dash/include/config.inc.php:ro" + - mrefd_data:/app/data + ports: + - ${HOST_DASHBOARD_PORT:-8080}:${CONTAINER_DASHBOARD_PORT:-80} + restart: unless-stopped +volumes: + mrefd_data: \ No newline at end of file diff --git a/php-dash/Containerfile b/php-dash/Containerfile new file mode 100644 index 0000000..56ed6f6 --- /dev/null +++ b/php-dash/Containerfile @@ -0,0 +1,3 @@ +FROM php:8.2-apache + +COPY . /var/www/html diff --git a/php-dash/include/functions.php b/php-dash/include/functions.php index 332199d..763e589 100644 --- a/php-dash/include/functions.php +++ b/php-dash/include/functions.php @@ -40,9 +40,14 @@ function elapsedTime($time) { } function FormatSeconds($seconds) { - $seconds = abs($seconds); - return sprintf("%d days %02d:%02d:%02d", $seconds/60/60/24,($seconds/60/60)%24,($seconds/60)%60,$seconds%60); -} + $seconds = abs($seconds); + return sprintf("%d days %02d:%02d:%02d", + intval($seconds / 86400), // days (86400 = 60*60*24) + intval($seconds / 3600) % 24, // hours (3600 = 60*60) + intval($seconds / 60) % 60, // minutes + $seconds % 60 // seconds + ); +} function CreateCode ($laenge) { $zeichen = "1234567890abcdefghijklmnopqrstuvwyxzABCDEFGHIJKLMNOPQRSTUVWYXZ";