Athas Boilerplate

CI/CD Operations

internal

Internal 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 Hardening is recorded in docs/decisions/012-ci-cd-release-model-hardening.md
  • ADR-013: Self-Hosted CI Runner Adoption Threshold is recorded in docs/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.

  • main is the production branch.
  • develop is 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:

  1. Frontend images were not environment-portable because VITE_* values were treated as build-time image properties.
  2. Workflow and root delivery-path changes could skip meaningful validation because CI was gated too aggressively on Nx affected project resolution.
  3. Mutable tags could race without workflow concurrency.
  4. Branch naming drifted across workflow files and deployment docs.
  5. Node patch versions drifted across local, CI, and Docker runtime images.
  6. 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 build work 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.0 in 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-cache package 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 stay read-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 port 9000.
  • 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-console and client-console do not currently expose explicit Nx typecheck targets, 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.

On this page