diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 74ba2dc4b..ed059fefc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,39 +1,113 @@ name: docker-build -on: [workflow_dispatch] +on: + pull_request: + paths: + - '.github/workflows/docker.yml' + - 'apps/web/**' + - 'apps/web-backend/**' + - 'docker/**' + - 'libs/**' + - 'package.json' + - 'pnpm-lock.yaml' + push: + branches: + - master + tags: + - 'v*' + workflow_dispatch: + inputs: + push: + description: 'Push the image to Docker Hub' + required: true + type: boolean + default: false + +permissions: + contents: read jobs: - build: - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v3 - - - name: Install jq - run: sudo apt-get update && sudo apt-get install -y jq - - - name: Get version from package.json - id: package-version - run: echo "VERSION=$(cat package.json | jq -r .version)" >> $GITHUB_OUTPUT - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: . - file: ./docker/Dockerfile - push: true - tags: | - 4gray/iptvnator:latest - 4gray/iptvnator:${{ github.sha }} - 4gray/iptvnator:${{ steps.package-version.outputs.VERSION }} - platforms: linux/amd64,linux/arm64 + build: + name: Build Docker image + runs-on: ubuntu-latest + timeout-minutes: 90 + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Prepare Docker metadata + id: docker-meta + shell: bash + run: | + set -euo pipefail + + version="$(node -p "require('./package.json').version")" + short_sha="${GITHUB_SHA::12}" + publish="false" + platforms="linux/amd64" + tags="4gray/iptvnator:pr-${{ github.event.pull_request.number || 'manual' }}" + + if [[ "${GITHUB_EVENT_NAME}" == "push" && "${GITHUB_REF}" == "refs/heads/master" ]]; then + publish="true" + platforms="linux/amd64,linux/arm64" + tags=$(cat <> "${GITHUB_OUTPUT}" + + - name: Login to Docker Hub + if: steps.docker-meta.outputs.publish == 'true' + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Build Docker image + uses: docker/build-push-action@v7 + with: + context: . + file: ./docker/Dockerfile + push: ${{ steps.docker-meta.outputs.publish == 'true' }} + tags: ${{ steps.docker-meta.outputs.tags }} + platforms: ${{ steps.docker-meta.outputs.platforms }} + cache-from: type=gha + cache-to: type=gha,mode=max,ignore-error=true diff --git a/docker/README.md b/docker/README.md index bc585c047..7906c6fa8 100644 --- a/docker/README.md +++ b/docker/README.md @@ -34,6 +34,29 @@ pnpm nx build web --configuration=pwa pnpm nx build web-backend ``` +## Published Docker Tags + +Pull request builds validate the Dockerfile without pushing an image. Docker +Hub publishing happens only from trusted repository events. +Publishing requires the repository secrets `DOCKERHUB_USERNAME` and +`DOCKERHUB_TOKEN`; pull request builds and default manual runs do not use those +secrets. + +| Tag pattern | Published from | Use case | +| -------------------------- | ------------------------ | ------------------------------------------------------------------------- | +| `latest` | `master` pushes | Default self-hosted image for users who want the newest merged PWA build. | +| `-pwa` | `master` pushes | Latest PWA image for the current `package.json` version. | +| `-pwa-` | `master` pushes | Immutable PWA image for a specific merged commit within a version. | +| `sha-` | `master` pushes | Commit-addressable image, useful for rollback and support diagnostics. | +| `` / `v` | `v*` release tags | Release image aligned with a repository release tag. | +| `stable` | Stable `v*` release tags | Most recent non-prerelease tagged release image. | +| `manual-` | Manual runs with `push` | Explicit maintainer-triggered rebuilds outside normal publish events. | + +Use `latest` for the simplest self-hosted setup. Pin `sha-` or +`-pwa-` when you need reproducible deployments. Use release tags +when you want the Docker image to track a tagged IPTVnator release rather than +every merge to `master`. + ## Runtime Configuration The container writes `/usr/share/nginx/html/assets/app-config.js` on startup.