From d94d75e605fbe8fe1655ca4740f5581a4bd56699 Mon Sep 17 00:00:00 2001 From: l5y <220195275+l5yth@users.noreply.github.com> Date: Fri, 31 Oct 2025 11:43:30 +0100 Subject: [PATCH] Ensure Docker images publish versioned tags (#403) --- .env.example | 3 +++ .github/workflows/docker.yml | 22 ++++++++++++++++------ DOCKER.md | 14 ++++++++------ README.md | 7 +++++-- configure.sh | 5 +++++ docker-compose.yml | 4 ++-- 6 files changed, 39 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index bfc1b4d..78135f1 100644 --- a/.env.example +++ b/.env.example @@ -71,6 +71,9 @@ INSTANCE_DOMAIN=mesh.example.org # Docker image architecture (linux-amd64, linux-arm64, linux-armv7) POTATOMESH_IMAGE_ARCH=linux-amd64 +# Docker image tag (use "latest" for the newest release or pin to vX.Y) +POTATOMESH_IMAGE_TAG=latest + # Docker Compose networking profile # Leave unset for Linux hosts (default host networking). # Set to "bridge" on Docker Desktop (macOS/Windows) if host networking diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a096236..90bfde8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -56,12 +56,17 @@ jobs: id: version run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - VERSION="${{ github.event.inputs.version }}" + RAW_VERSION="${{ github.event.inputs.version }}" else - VERSION=${GITHUB_REF#refs/tags/v} + RAW_VERSION=${GITHUB_REF#refs/tags/} fi - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "Published version: $VERSION" + + STRIPPED_VERSION=${RAW_VERSION#v} + + echo "version=$STRIPPED_VERSION" >> $GITHUB_OUTPUT + echo "version_with_v=v$STRIPPED_VERSION" >> $GITHUB_OUTPUT + echo "raw_version=$RAW_VERSION" >> $GITHUB_OUTPUT + echo "Published version: $STRIPPED_VERSION" - name: Build and push ${{ matrix.service }} for ${{ matrix.architecture.name }} uses: docker/build-push-action@v5 @@ -74,6 +79,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:latest ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:${{ steps.version.outputs.version }} + ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-${{ matrix.service }}-${{ matrix.architecture.name }}:${{ steps.version.outputs.version_with_v }} labels: | org.opencontainers.image.source=https://github.com/${{ github.repository }} org.opencontainers.image.description=PotatoMesh ${{ matrix.service == 'web' && 'Web Application' || 'Python Ingestor' }} for ${{ matrix.architecture.label }} @@ -111,12 +117,15 @@ jobs: - name: Extract version from tag id: version run: | - VERSION=${GITHUB_REF#refs/tags/v} - echo "version=$VERSION" >> $GITHUB_OUTPUT + RAW_VERSION=${GITHUB_REF#refs/tags/} + STRIPPED_VERSION=${RAW_VERSION#v} + echo "version=$STRIPPED_VERSION" >> $GITHUB_OUTPUT + echo "version_with_v=v$STRIPPED_VERSION" >> $GITHUB_OUTPUT - name: Test web application (Linux AMD64) run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version }} + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-web-linux-amd64:${{ steps.version.outputs.version_with_v }} docker run --rm -d --name web-test -p 41447:41447 \ -e API_TOKEN=test-token \ -e DEBUG=1 \ @@ -128,6 +137,7 @@ jobs: - name: Test ingestor (Linux AMD64) run: | docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:${{ steps.version.outputs.version }} + docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}-ingestor-linux-amd64:${{ steps.version.outputs.version_with_v }} docker run --rm --name ingestor-test \ -e POTATOMESH_INSTANCE=http://localhost:41447 \ -e API_TOKEN=test-token \ diff --git a/DOCKER.md b/DOCKER.md index 9cb71b7..2c1d1be 100644 --- a/DOCKER.md +++ b/DOCKER.md @@ -13,13 +13,15 @@ will pull the latest release images for you. ## Images on GHCR -| Service | Image | -|----------|-------------------------------------------------------------------| -| Web UI | `ghcr.io/l5yth/potato-mesh-web-linux-amd64:latest` | -| Ingestor | `ghcr.io/l5yth/potato-mesh-ingestor-linux-amd64:latest` | +| Service | Image | +|----------|---------------------------------------------------------------------------------------------------------------| +| Web UI | `ghcr.io/l5yth/potato-mesh-web-linux-amd64:` (e.g. `latest`, `3.0`, or `v3.0`) | +| Ingestor | `ghcr.io/l5yth/potato-mesh-ingestor-linux-amd64:` (e.g. `latest`, `3.0`, or `v3.0`) | -Images are published for every tagged release. Replace `latest` with a -specific version tag if you prefer pinned deployments. +Images are published for every tagged release. Each build receives both semantic +version tags (for example `3.0`) and a matching `v`-prefixed tag (for example +`v3.0`). `latest` always points to the newest release, so pin one of the version +tags when you need a specific build. ## Configure environment diff --git a/README.md b/README.md index 5412ed6..3cc89fa 100644 --- a/README.md +++ b/README.md @@ -202,11 +202,14 @@ Post your nodes here: Docker images are published on Github for each release: ```bash -docker pull ghcr.io/l5yth/potato-mesh/web:latest +docker pull ghcr.io/l5yth/potato-mesh/web:latest # newest release +docker pull ghcr.io/l5yth/potato-mesh/web:v3.0 # pinned historical release docker pull ghcr.io/l5yth/potato-mesh/ingestor:latest ``` -See the [Docker guide](DOCKER.md) for more details and custome deployment instructions. +Set `POTATOMESH_IMAGE_TAG` in your `.env` (or environment) to deploy a specific +tagged release with Docker Compose. See the [Docker guide](DOCKER.md) for more +details and custom deployment instructions. ## License diff --git a/configure.sh b/configure.sh index be1d705..4203fb6 100755 --- a/configure.sh +++ b/configure.sh @@ -81,6 +81,7 @@ MAX_DISTANCE=$(grep "^MAX_DISTANCE=" .env 2>/dev/null | cut -d'=' -f2- | tr -d ' CONTACT_LINK=$(grep "^CONTACT_LINK=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "#potatomesh:dod.ngo") API_TOKEN=$(grep "^API_TOKEN=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "") POTATOMESH_IMAGE_ARCH=$(grep "^POTATOMESH_IMAGE_ARCH=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "linux-amd64") +POTATOMESH_IMAGE_TAG=$(grep "^POTATOMESH_IMAGE_TAG=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "latest") INSTANCE_DOMAIN=$(grep "^INSTANCE_DOMAIN=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "") DEBUG=$(grep "^DEBUG=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "0") CONNECTION=$(grep "^CONNECTION=" .env 2>/dev/null | cut -d'=' -f2- | tr -d '"' || echo "/dev/ttyACM0") @@ -122,6 +123,8 @@ echo "🛠 Docker Settings" echo "------------------" echo "Specify the Docker image architecture for your host (linux-amd64, linux-arm64, linux-armv7)." read_with_default "Docker image architecture" "$POTATOMESH_IMAGE_ARCH" POTATOMESH_IMAGE_ARCH +echo "Enter the Docker image tag to deploy (use 'latest' for the newest release or pin a version such as v3.0)." +read_with_default "Docker image tag (latest, vX.Y, etc.)" "$POTATOMESH_IMAGE_TAG" POTATOMESH_IMAGE_TAG echo "" echo "🔌 Ingestor Connection" @@ -182,6 +185,7 @@ update_env "CONTACT_LINK" "\"$CONTACT_LINK\"" update_env "DEBUG" "$DEBUG" update_env "API_TOKEN" "$API_TOKEN" update_env "POTATOMESH_IMAGE_ARCH" "$POTATOMESH_IMAGE_ARCH" +update_env "POTATOMESH_IMAGE_TAG" "$POTATOMESH_IMAGE_TAG" update_env "FEDERATION" "$FEDERATION" update_env "PRIVATE" "$PRIVATE" update_env "CONNECTION" "$CONNECTION" @@ -226,6 +230,7 @@ echo " Debug Logging: ${DEBUG}" echo " Connection: ${CONNECTION}" echo " API Token: ${API_TOKEN:0:8}..." echo " Docker Image Arch: $POTATOMESH_IMAGE_ARCH" +echo " Docker Image Tag: $POTATOMESH_IMAGE_TAG" echo " Private Mode: ${PRIVATE}" echo " Instance Domain: ${INSTANCE_DOMAIN:-'Auto-detected'}" if [ "${FEDERATION:-1}" = "0" ]; then diff --git a/docker-compose.yml b/docker-compose.yml index 64ed571..57d3210 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,5 @@ x-web-base: &web-base - image: ghcr.io/l5yth/potato-mesh-web-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:latest + image: ghcr.io/l5yth/potato-mesh-web-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:${POTATOMESH_IMAGE_TAG:-latest} environment: APP_ENV: ${APP_ENV:-production} RACK_ENV: ${RACK_ENV:-production} @@ -30,7 +30,7 @@ x-web-base: &web-base cpus: '0.25' x-ingestor-base: &ingestor-base - image: ghcr.io/l5yth/potato-mesh-ingestor-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:latest + image: ghcr.io/l5yth/potato-mesh-ingestor-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:${POTATOMESH_IMAGE_TAG:-latest} environment: CONNECTION: ${CONNECTION:-/dev/ttyACM0} CHANNEL_INDEX: ${CHANNEL_INDEX:-0}