feat(ci): Forgejo Actions deploy workflow for home-ctr-onyx (#30)
On push to main, the homelab runner (container mode, docker socket mounted) builds the image, pushes it to the Forgejo registry tagged with the commit SHA and latest, then runs docker compose pull + up -d directly against the host Docker daemon — no SSH hop, since the runner already lives on the deploy host. Finishes with one curl -u admin:... against https://quartermaster.unbiasedgeek.com/healthz to catch TLS, Traefik routing, and basic-auth regressions in a single probe. Two repo-scoped secrets required: REGISTRY_TOKEN for docker login and QUARTERMASTER_SMOKE_PASSWORD for the public healthz probe. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7abed176e3
commit
df4fcfc659
2 changed files with 93 additions and 0 deletions
62
.forgejo/workflows/deploy.yml
Normal file
62
.forgejo/workflows/deploy.yml
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
name: deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-push-deploy:
|
||||
runs-on: homelab
|
||||
env:
|
||||
REGISTRY: forgejo.labbity.unbiasedgeek.com
|
||||
IMAGE: forgejo.labbity.unbiasedgeek.com/archeious/quartermaster/quartermaster
|
||||
COMPOSE_PROJECT_NAME: quartermaster
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Forgejo registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: archeious
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
- name: Build and push image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.IMAGE }}:${{ github.sha }}
|
||||
${{ env.IMAGE }}:latest
|
||||
|
||||
- name: Deploy
|
||||
run: |
|
||||
set -euo pipefail
|
||||
printf 'QUARTERMASTER_TAG=%s\n' '${{ github.sha }}' > .env
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
- name: Smoke test
|
||||
env:
|
||||
SMOKE_PASSWORD: ${{ secrets.QUARTERMASTER_SMOKE_PASSWORD }}
|
||||
run: |
|
||||
set -eu
|
||||
for attempt in 1 2 3 4 5 6 7 8 9 10; do
|
||||
code=$(curl -sS -o /dev/null -w '%{http_code}' \
|
||||
-u "admin:$SMOKE_PASSWORD" \
|
||||
https://quartermaster.unbiasedgeek.com/healthz || echo "000")
|
||||
if [ "$code" = "200" ]; then
|
||||
echo "smoke OK after $attempt attempt(s)"
|
||||
exit 0
|
||||
fi
|
||||
echo "attempt $attempt: got $code, retrying"
|
||||
sleep 3
|
||||
done
|
||||
echo "smoke FAILED — last code $code"
|
||||
exit 1
|
||||
31
README.md
31
README.md
|
|
@ -167,3 +167,34 @@ editing the checked-in compose file.
|
|||
path. Three would resolve relative to the working directory, and the
|
||||
SQLite file would NOT land on the bind mount (on next restart the
|
||||
database would be empty).
|
||||
|
||||
## CI/CD
|
||||
|
||||
Push to `main` triggers `.forgejo/workflows/deploy.yml` on the
|
||||
`homelab` runner. That runner lives on home-ctr-onyx itself in
|
||||
container mode with the host's Docker socket mounted — so the
|
||||
workflow talks to the same Docker daemon that hosts the production
|
||||
container and no SSH round-trip is needed.
|
||||
|
||||
The workflow: checks out the repo, builds the image, pushes it to
|
||||
the Forgejo registry tagged with the commit SHA and `latest`,
|
||||
writes `QUARTERMASTER_TAG=<git-sha>` to a `.env` file next to the
|
||||
checked-out `compose.yml`, runs `docker compose pull && docker
|
||||
compose up -d`, and finishes with one
|
||||
`curl -fsS -u admin:… https://quartermaster.unbiasedgeek.com/healthz`
|
||||
against the public URL — catching TLS, Traefik routing, and the
|
||||
basic-auth middleware in a single probe.
|
||||
|
||||
The workflow reads two Forgejo Actions secrets (repo-scoped under
|
||||
`archeious/quartermaster`):
|
||||
|
||||
* `REGISTRY_TOKEN` — archeious Forgejo personal token with
|
||||
`write:package` scope; used as the docker-login password.
|
||||
* `QUARTERMASTER_SMOKE_PASSWORD` — plaintext basic-auth password
|
||||
for the `admin` user, delivered to the tenant out-of-band by the
|
||||
platform team.
|
||||
|
||||
Rollback is manual for v1: `git checkout` the previous SHA, set
|
||||
`QUARTERMASTER_TAG` in `.env` to that SHA, and `docker compose up -d`
|
||||
from a clone of the repo (or let the previous commit be the `main`
|
||||
tip and the deploy workflow will roll it out).
|
||||
|
|
|
|||
Loading…
Reference in a new issue