Onboard an app
Onboarding an app onto Ultron Infra (the ultron node) means wiring it through
the platform’s standard GitOps pipeline: build an image, push it
to GHCR, point an Argo CD Application at a workloads/<app>/
folder, and let Argo Rollouts ship it behind a
Prometheus gate. Nothing is applied by hand — you commit YAML
and Argo CD reconciles.
This page is the reusable recipe. Every value below is a placeholder: <app> is your
app/namespace, <owner> your GitHub owner, <domain> / <auth-domain> your
hostnames. Swap them and the same steps onboard any app. See /examples/ for a
filled-in worked example.
The pipeline
Section titled “The pipeline”flowchart LR
Code([push to app repo]) --> CI[GitHub Actions<br/>buildx linux/arm64]
CI --> Img[/ghcr.io/owner/app:sha-XXXX/]
Img --> Bump[bump tag in<br/>workloads/app/rollout.yaml]
Bump --> Sync[Argo CD sync]
Sync --> Pre[migrations Job<br/>PreSync hook]
Pre --> Roll[Rollout canary<br/>25 → 50 → 75 → 100%]
Roll --> Gate{Prometheus<br/>success-rate ≥ 95%?}
Gate -->|yes| Prod[promoted]
Gate -->|no| RB[auto-rollback]
The image tag in Git is the deploy trigger: CI produces sha-<short>, you bump that
tag in rollout.yaml, push, and Argo CD does the rest. Migrations run before new
pods start (a PreSync hook); the canary then steps traffic up
while an AnalysisTemplate watches the success rate and
aborts on regression.
The recipe
Section titled “The recipe”Work through these in order — each is a copy-paste template keyed on <app>:
- Build & CI — multi-stage distroless Dockerfile
(cross-compiled arm64, migrate CLI bundled),
.dockerignore, and a GitHub Actions workflow that pushes to GHCR. - GitOps & deploy — the
apps/<app>.yamlArgoApplication, theworkloads/<app>/skeleton, and the Rollout / Service / Ingress manifests. - Database & migrations — a
CNPG
Cluster, readingDB_URLfrom its auto-generated Secret, and the migrations PreSyncJob. - Canary & metrics — exposing
/metrics, theServiceMonitor, theAnalysisTemplate, and the Rollout canary gate. - Secrets — the out-of-band secret pattern and the
GHCR public-package vs
imagePullSecretchoice.
Folder layout
Section titled “Folder layout”A new app touches exactly two places in the gitops repo:
gitops/├── apps/│ └── <app>.yaml # Argo CD Application → workloads/<app>└── workloads/ └── <app>/ ├── namespace.yaml ├── postgres-cluster.yaml # if the app needs a DB ├── migrations-job.yaml # if the app has migrations ├── configmap.yaml # non-secret env ├── rollout.yaml ├── service.yaml ├── ingress.yaml ├── servicemonitor.yaml ├── analysistemplate.yaml └── scheduledbackup.yaml # if the app has a DBBecause the root app watches apps/, the new apps/<app>.yaml is picked up
automatically — no extra registration step.