The path from main-branch code to running production on docker1. This is the release runbook; generic Docker operation for any installation is covered by WikantikOnDocker.
bin/run-tests.sh --parallel 4 (unit phase + parallel IT phase) is the canonical pre-commit/pre-release gate; the header of cut-release.sh asks for bin/run-tests.sh --all, which adds the opt-in Authentik SCIM full-loop so a release keeps it from rotting. This matters doubly here because the release CI does not run tests, and on a push to main CI runs only the static gates (build without tests, PMD complexity ratchet, frontend lint/audit/vitest, shell-tool tests, OSV scan) — the Java unit suite and coverage floors run only in the weekly Quality Gates job. Confirm the latest Quality Gates run on main is green (gh run list --workflow=quality-gates.yml) before tagging.bin/cut-release.sh X.Y.Z (no v prefix) requires a clean tree on main and a ## [Unreleased] section in CHANGELOG.md. It sets the version in every pom.xml, renames [Unreleased] to [X.Y.Z] - <today>, commits release: X.Y.Z, tags vX.Y.Z, then bumps main to the next -SNAPSHOT (a second commit) — all locally, before it asks to push. It does not build or test. Known quirk: with no TTY it exits 1 at the push confirmation — the commits and tag already exist; finish with git push origin main vX.Y.Z.release.yml on GitHub-hosted runners (ci-cd.yml and staging-deploy.yml target self-hosted and are manual-only; no self-hosted runner has been registered since ~May 2026, so jobs targeting it queue forever). It builds the WAR with -DskipTests, then builds and pushes the multi-arch (linux/amd64 and linux/arm64) image ghcr.io/jakefearsd/wikantik:X.Y.Z plus :latest — note the image tag has no v prefix — in roughly 22 minutes, and creates a GitHub Release with the WAR attached and notes taken from CHANGELOG.md. It skips the test suite by design.bin/deploy-release.sh X.Y.Z pulls the released image on the developer box, tags it wikantik:latest, and runs bin/remote.sh deploy --skip-build (snapshot the running image as :rollback, docker save | ssh docker load, up -d). Equivalently bin/remote.sh deploy --pull X.Y.Z makes the host pull the image from GHCR directly. Either path polls /api/health and auto-rolls-back on a failed health check. The container entrypoint applies any new bin/db/migrations/V*.sql migrations on start, so a routine release needs no manual database step. Manual rollback is bin/remote.sh rollback (re-promotes the :rollback tag) or bin/remote.sh rollback --to X.Y.Z for one of the newest five retained version tags.bin/remote.sh status (health + container ps + disk + pages size); watch the wikantik dashboards on docker2.In this project, "minor release" colloquially means a patch bump (2.3.x → 2.3.x+1). Never bump the SemVer minor without an explicit decision — this has caused an unwind before.
A deploy replaces the application container only. The database, page store, and search indexes persist — corpus changes travel by a different path entirely: Wikantik Content vs Code Deployment.