Publish container image to Gitea Packages and switch netcup deploy to pull #39

Closed
opened 2026-04-29 01:31:44 +02:00 by libretech · 1 comment
Owner

Summary

Wire the existing .gitea/workflows/deploy.yml job to publish the librenotes container image to a registry on every push to main and on tag v*, and switch the netcup deployment from build-on-host to pull-on-host. Currently the deploy job is gated on vars.DEPLOY_ENABLED == 'true' and skipped because no registry/secrets exist; netcup builds the image locally via compose.netcup.yaml (build: .).

Background

  • v0.1.0 is tagged but no image artifact exists.
  • Gitea's built-in container registry is available at git.librete.ch/v2/<owner>/<image> and authenticates with a personal/robot access token.
  • A registered netcup runner (label ubuntu-latest) already executes CI workflows.

Tasks

  • Create a Gitea robot account or scoped personal access token with package:write on public org
  • Set repo secrets:
    • REGISTRY=git.librete.ch
    • REGISTRY_USER=<robot-name>
    • REGISTRY_PASS=<token>
    • DEPLOY_HOST=root@netcup
    • DEPLOY_KEY=<deploy SSH private key> (issue/track via separate ops issue if needed)
    • DEPLOY_PATH=/srv/librenotes
    • HEALTH_URL=https://ln.cloud.librete.ch/healthz
  • Set repo variable DEPLOY_ENABLED=true
  • Replace compose.netcup.yaml build: . with image: ${LIBRENOTES_IMAGE} and resolve LIBRENOTES_IMAGE from .env on the host (e.g. git.librete.ch/public/librenotes:main)
  • Verify a main push triggers build → push → deploy → health check
  • Verify a v* tag push pins the immutable tag in LIBRENOTES_IMAGE on the host

Acceptance Criteria

  • git.librete.ch/public/librenotes:main and git.librete.ch/public/librenotes:v0.1.0 exist as packages
  • Deploy job runs and turns green on a main push
  • /srv/librenotes/ no longer needs a Go toolchain or build context (only compose.netcup.yaml + .env)
  • Rollback documented: edit LIBRENOTES_IMAGE to a prior tag and docker compose ... up -d

Dependencies

  • Depends on #30 (release pipeline foundation, closed)
## Summary Wire the existing `.gitea/workflows/deploy.yml` job to publish the librenotes container image to a registry on every push to `main` and on tag `v*`, and switch the netcup deployment from build-on-host to pull-on-host. Currently the deploy job is gated on `vars.DEPLOY_ENABLED == 'true'` and skipped because no registry/secrets exist; netcup builds the image locally via `compose.netcup.yaml` (`build: .`). ## Background - v0.1.0 is tagged but no image artifact exists. - Gitea's built-in container registry is available at `git.librete.ch/v2/<owner>/<image>` and authenticates with a personal/robot access token. - A registered netcup runner (label `ubuntu-latest`) already executes CI workflows. ## Tasks - [ ] Create a Gitea robot account or scoped personal access token with `package:write` on `public` org - [ ] Set repo secrets: - `REGISTRY=git.librete.ch` - `REGISTRY_USER=<robot-name>` - `REGISTRY_PASS=<token>` - `DEPLOY_HOST=root@netcup` - `DEPLOY_KEY=<deploy SSH private key>` (issue/track via separate ops issue if needed) - `DEPLOY_PATH=/srv/librenotes` - `HEALTH_URL=https://ln.cloud.librete.ch/healthz` - [ ] Set repo variable `DEPLOY_ENABLED=true` - [ ] Replace `compose.netcup.yaml` `build: .` with `image: ${LIBRENOTES_IMAGE}` and resolve `LIBRENOTES_IMAGE` from `.env` on the host (e.g. `git.librete.ch/public/librenotes:main`) - [ ] Verify a `main` push triggers build → push → deploy → health check - [ ] Verify a `v*` tag push pins the immutable tag in `LIBRENOTES_IMAGE` on the host ## Acceptance Criteria - [ ] `git.librete.ch/public/librenotes:main` and `git.librete.ch/public/librenotes:v0.1.0` exist as packages - [ ] Deploy job runs and turns green on a `main` push - [ ] `/srv/librenotes/` no longer needs a Go toolchain or build context (only `compose.netcup.yaml` + `.env`) - [ ] Rollback documented: edit `LIBRENOTES_IMAGE` to a prior tag and `docker compose ... up -d` ## Dependencies - Depends on #30 (release pipeline foundation, closed)
libretech added the taskinfrastructure labels 2026-04-29 01:31:44 +02:00
Author
Owner

All criteria met as of 2026-04-29T13:25:34Z:

  • git.librete.ch/public/librenotes:main and :sha-2c20edb published as packages.
  • Deploy job runs and turns green on a main push (run #30, success).
  • /srv/librenotes/ uses pull-only flow: compose.yaml + compose.netcup.yaml + .env (LIBRENOTES_IMAGE=git.librete.ch/public/librenotes:main). No build context on the host.
  • Rollback documented in docs/operations.md (perl edit of LIBRENOTES_IMAGE + compose pull && up -d).
  • https://ln.cloud.librete.ch/healthz returns 200.

Follow-ups for tag-push pinning will land via #41 (backups) and #40 (SMTP) tracks; the build/push/deploy pipeline itself is complete.

All criteria met as of 2026-04-29T13:25:34Z: - `git.librete.ch/public/librenotes:main` and `:sha-2c20edb` published as packages. - Deploy job runs and turns green on a main push (run #30, success). - /srv/librenotes/ uses pull-only flow: `compose.yaml` + `compose.netcup.yaml` + `.env` (LIBRENOTES_IMAGE=git.librete.ch/public/librenotes:main). No build context on the host. - Rollback documented in docs/operations.md (perl edit of LIBRENOTES_IMAGE + compose pull && up -d). - https://ln.cloud.librete.ch/healthz returns 200. Follow-ups for tag-push pinning will land via #41 (backups) and #40 (SMTP) tracks; the build/push/deploy pipeline itself is complete.
Sign in to join this conversation.