# Build and publish the app + bot container images to Gitea's container registry # on every merge to main. Production then pulls prebuilt images instead of # building on the host. # # Prerequisites (one-time): # • An always-on Gitea runner with label `ubuntu-latest` whose jobs have the # host Docker socket mounted (/var/run/docker.sock), so `docker build` talks # to the host daemon. This also gives free layer caching between runs. # • Two repo secrets (Settings → Actions → Secrets): # REGISTRY_USER — the Gitea username that owns the token below # REGISTRY_TOKEN — a Gitea access token with `write:package` (+ read:package) # See the PR description / README for step-by-step token creation. # # Produces, in gitea.whitlocktech.com// : # website-app:latest + website-app:sha-<7> # website-bot:latest + website-bot:sha-<7> name: Build container images on: push: branches: [main] workflow_dispatch: {} concurrency: group: images-${{ github.ref }} cancel-in-progress: true env: REGISTRY: gitea.whitlocktech.com jobs: build: runs-on: ubuntu-latest steps: - name: Check out the merged commit uses: actions/checkout@v4 - name: Derive image refs (registry owner must be lowercase for Docker) run: | set -euo pipefail OWNER="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')" SHORT_SHA="${GITHUB_SHA:0:7}" echo "APP_IMAGE=${REGISTRY}/${OWNER}/website-app" >> "$GITHUB_ENV" echo "BOT_IMAGE=${REGISTRY}/${OWNER}/website-bot" >> "$GITHUB_ENV" echo "TAG=sha-${SHORT_SHA}" >> "$GITHUB_ENV" - name: Verify the Docker daemon is reachable # Fails fast with a clear message if the host socket isn't mounted into # the job container (the one hard runner prerequisite). run: | set -euo pipefail if ! docker info >/dev/null 2>&1; then echo "::error::Docker daemon not reachable. Mount /var/run/docker.sock into the runner's job containers." exit 1 fi echo "Docker daemon OK" - name: Log in to the Gitea container registry run: | set -euo pipefail echo "${{ secrets.REGISTRY_TOKEN }}" \ | docker login "${REGISTRY}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin - name: Build & push the app image (server + client) run: | set -euo pipefail docker build -f Dockerfile \ -t "${APP_IMAGE}:latest" \ -t "${APP_IMAGE}:${TAG}" \ . docker push "${APP_IMAGE}:latest" docker push "${APP_IMAGE}:${TAG}" - name: Build & push the bot image run: | set -euo pipefail docker build -f bot/Dockerfile \ -t "${BOT_IMAGE}:latest" \ -t "${BOT_IMAGE}:${TAG}" \ . docker push "${BOT_IMAGE}:latest" docker push "${BOT_IMAGE}:${TAG}" - name: Log out (clear cached credentials from the runner) if: always() run: docker logout "${REGISTRY}" || true