Skip to content

Build & deploy

emergent deploys onto Kubernetes (local k3s for development) via Helm + Helmfile, with container images produced by an in-cluster Argo Workflows build path. There are no Dockerfiles or docker-compose in the app deploy path; container-backed tests use podman-compose under infra/compose/.

The unified build path bundles each app as a static -data image (for example docs-data, docs-eng-data) that a runtime chart serves. Two entrypoints wrap it:

  • bun run build:argo:localscripts/local-build-push-argo-oci.sh — builds and pushes from a local checkout. It sources vars.sh, manages the emergent-source-pv PersistentVolume, and drives the Argo workflow (WORKFLOW_TIMEOUT configurable).
  • bun run build:argo:remotescripts/remote-build-push-argo-oci.sh — the remote-source variant.

bun run build itself is the plain turbo build (turbo run build) that produces each app’s dist/; the Argo scripts are what package and push OCI images.

infra/helmfile/ holds the Helmfile specs (helmfile.yaml, helmfile-build.yaml, helmfile-infra.yaml and their .gotmpl forms) plus per-environment values/. The emergent chart lives in infra/charts/emergent. The infra/k3s-deploy/ scripts, surfaced as bun run tasks, drive a local cluster:

  • k3s:bootstrap / k3s:bootstrap:infrabootstrap-cluster.sh / bootstrap-infra-cluster.sh — stand up the app and infra clusters.
  • k3s:install:appshelmfile-install.sh — install the app releases.
  • k3s:install:buildhelmfile-build.sh — the build-path releases (Argo Workflows).
  • k3s:install:infrahelmfile-infra-install.sh — infra dependencies.
  • k3s:install:cluster-serviceshelmfile-cluster-install.sh — shared cluster services.

Preview changes with mise run helm-diff (helmfile -f infra/helmfile/helmfile.yaml diff).

Both documentation sites deploy in-cluster as static -data bundle images through this same Argo build path, with entries in the emergent chart (ADR-0051):

  • apps/docs (end-user) takes the durable docs.… hostname (VITE_DOCS_DOMAIN) and is the surface that later fronts the public presence.
  • apps/docs-eng (this site) is internal: enabled only in dev/internal environments’ values (docsEng chart key). Environment membership is the access boundary; a public-facing environment simply never deploys it.

Per-environment values live under infra/helmfile/values/; non-dev environments layer a private values file. Cluster and namespace targeting flows from vars.sh (+ gitignored vars.local.sh). Secrets are sops/age-encrypted under infra/secrets/ — never commit plaintext.

For the design rationale, see the architecture tree and the relevant ADRs.