CI/CD Operations
internalInternal release model, findings archive, and current shipping rules for GitHub Actions plus Dokploy.
CI/CD Operations
This page captures the current internal shipping model after the March 2026 CI/CD hardening pass.
Canonical decision:
ADR-012: CI/CD Release Model Hardeningis recorded indocs/decisions/012-ci-cd-release-model-hardening.mdADR-013: Self-Hosted CI Runner Adoption Thresholdis recorded indocs/decisions/013-self-hosted-ci-runner-adoption-threshold.md
Operational references:
Chosen Path
We are following the implemented code path and aligning docs to it.
mainis the production branch.developis the integration/staging branch when used.- Backend, admin console, and client console are CI-built artifacts.
- Docs keeps Git build-on-deploy as the default Dokploy path.
- Frontend public env configuration is runtime-injected, not image-baked.
Findings Archive
These were the main issues found during review:
- Frontend images were not environment-portable because
VITE_*values were treated as build-time image properties. - Workflow and root delivery-path changes could skip meaningful validation because CI was gated too aggressively on Nx affected project resolution.
- Mutable tags could race without workflow concurrency.
- Branch naming drifted across workflow files and deployment docs.
- Node patch versions drifted across local, CI, and Docker runtime images.
- Docker CI was doing redundant work and lacked basic context/cache hygiene.
What Changed
- Workflow-level concurrency now prevents overlapping runs from racing moving image tags.
- Delivery-path changes trigger full CI scope.
- Dokploy deploys can be triggered directly from GitHub Actions through Dokploy's deploy API instead of relying on external-registry webhook assumptions, but that path stays opt-in behind
ENABLE_DOKPLOY_DEPLOY_API=true. - Docker image jobs no longer do redundant host-side
bun install+nx buildwork before the Docker build. - Buildx GitHub cache is enabled for image builds.
- Docker contexts are reduced via a repo-level
.dockerignore. - Node is pinned to
24.12.0in CI and Dockerfiles. - Web apps inject public runtime config through the SSR document shell.
Current Rules
- Use SHA tags for rollback and controlled promotions.
- Treat moving tags as convenience channels only.
- Keep runtime public env values limited to non-secret
VITE_*keys. - For GHCR/external registry applications, prefer GitHub Actions -> Dokploy API deploy triggers.
- If workflow files, Dockerfiles, root package manager files, or root tooling scripts change, expect full CI.
Next Improvement
The next CI speed lever is remote Nx task caching, and the chosen direction is MinIO-backed S3 cache.
- Nx local cache is enabled today.
- GitHub Actions cache helps restore
.nx/cache, but it is not a true shared remote task cache. - We added the official
@nx/s3-cachepackage plus a repo-local wrapper script so cache configuration is only injected when the required env vars exist. - For GitHub-hosted runners, MinIO is the practical self-hosted option. Shared-filesystem cache only helps if runners can mount the same directory.
- Pull requests from branches in this repository can use
read-write; forked pull requests stayread-only. - Trusted branch pushes also use
read-write. - MinIO must expose the S3 API endpoint, not only the console. MinIO console is typically port
9001; S3 API is typically port9000. - Use a dedicated access key for CI instead of the MinIO root credentials.
Required GitHub Configuration For MinIO
- Secret:
NX_KEY - Secret:
NX_S3_ACCESS_KEY_ID - Secret:
NX_S3_SECRET_ACCESS_KEY - Variable:
NX_S3_BUCKET - Variable:
NX_S3_ENDPOINT - Variable:
NX_S3_REGION - Optional variable:
NX_S3_FORCE_PATH_STYLE=true - Optional variable:
NX_S3_CACHE_KEY_PREFIX=athas-boilerplate - Optional variable:
NX_S3_DISABLE_CHECKSUM=true
Current Blocker
The MinIO URL currently shared in discussion is the browser console endpoint on port 9001. GitHub Actions needs a reachable S3 API endpoint for the cache, usually HTTPS forwarded to MinIO port 9000.
There is also a separate correctness gap:
admin-consoleandclient-consoledo not currently expose explicit Nxtypechecktargets, so they are validated primarily through build-time checks rather than dedicated CI typecheck tasks.
Deferred Option
Self-hosted GitHub Actions runners are intentionally not the next priority.
- They remain a valid future optimization.
- They should not be adopted on the production Dokploy VPS without measured spare capacity.
- A dedicated build machine is preferred over adding CI load directly to the application host.
- If we revisit them, preserve GitHub-hosted fallback and treat runner selection as an infrastructure toggle, not a release-model rewrite.