# Deploy: build → push → nomad job run, on every push to master. # # Runner requirements (Forgejo VPS, via the docker-compose stack there): # - DinD daemon also listens on unix:///var/run/docker.sock (so the job's # docker:28-cli container can reach it via -v /var/run/docker.sock); # - runner config valid_volumes allows '**' (the job mounts that socket). # nomad CLI is NOT extracted into the job container — the binary is # glibc-dynamically-linked and won't exec in Alpine; instead the Deploy step # runs `nomad` inside the hashicorp/nomad:1.9 image (which has the loader). # # Repo secrets (Settings → Secrets): # REGISTRY_TOKEN forgejo token, write:package scope (docker login) # NOMAD_TOKEN CI ACL token from deploy/nomad/README.md §5 # NOMAD_CACERT contents of nomad-ca.crt from README §3 # Repo variables (Settings → Variables): # NOMAD_ADDR_HOST services VPS public IP or DNS name (API :4646) # Registry location is baked below (resolved): p2gnl.mu-dungeon.xyz/admin-git name: deploy on: push: branches: [master] env: REGISTRY_HOST: p2gnl.mu-dungeon.xyz REGISTRY_OWNER: admin-git jobs: build-and-deploy: runs-on: ubuntu-latest container: image: docker:28-cli options: --volume /var/run/docker.sock:/var/run/docker.sock steps: - name: Checkout run: | apk add --no-cache git git init -q . git remote add origin ${{ github.server_url }}/${{ github.repository }}.git git fetch --depth 1 origin ${{ github.sha }} git checkout -q FETCH_HEAD - name: Registry login env: REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }} run: | [ -n "$REGISTRY_TOKEN" ] || { echo "REGISTRY_TOKEN secret is empty"; exit 1; } docker login "$REGISTRY_HOST" -u "$REGISTRY_OWNER" -p "$REGISTRY_TOKEN" - name: Build & push images (SHA tag) run: | set -e TAG="${{ github.sha }}" for name in api worker-extract worker-analyze worker-prescreen worker-billing worker-notify; do image="$REGISTRY_HOST/$REGISTRY_OWNER/contract-check-$name" docker build -f "srv/$name/Dockerfile" -t "$image:$TAG" . docker push "$image:$TAG" done - name: Deploy to Nomad # nomad runs inside its own image (glibc-dynamically-linked binary # won't exec in Alpine-based docker:28-cli). Files reach the nomad # container via `docker cp` (tar stream) — NOT bind mounts, because # the workspace lives in the job container's overlay, not on the DinD # daemon's host filesystem (bind sources resolve daemon-side). env: NOMAD_ADDR_HOST: ${{ vars.NOMAD_ADDR_HOST }} NOMAD_TOKEN: ${{ secrets.NOMAD_TOKEN }} NOMAD_CACERT: ${{ secrets.NOMAD_CACERT }} run: | [ -n "$NOMAD_ADDR_HOST" ] || { echo "NOMAD_ADDR_HOST variable is empty"; exit 1; } [ -n "$NOMAD_TOKEN" ] || { echo "NOMAD_TOKEN secret is empty"; exit 1; } [ -n "$NOMAD_CACERT" ] || { echo "NOMAD_CACERT secret is empty"; exit 1; } mkdir -p .ci-tls printf '%s\n' "$NOMAD_CACERT" > .ci-tls/ca.crt docker create --name nomad-deploy \ -e IMAGE_TAG="${{ github.sha }}" \ -e NOMAD_ADDR="https://$NOMAD_ADDR_HOST:4646" \ -e NOMAD_CACERT=/tmp/ca.crt \ -e NOMAD_TOKEN="$NOMAD_TOKEN" \ --entrypoint /bin/nomad \ hashicorp/nomad:1.9 job run /tmp/job.hcl docker cp .ci-tls/ca.crt nomad-deploy:/tmp/ca.crt docker cp deploy/nomad/contract-check.nomad.hcl nomad-deploy:/tmp/job.hcl docker start -a nomad-deploy rc=$? docker rm nomad-deploy >/dev/null rm -rf .ci-tls exit $rc