K8s manifests and ArgoCD applications for student projects on the UNICAMP IC cluster (ak8s.ic.unicamp.br).
.
├── apps/ # Deployed applications
│ └── mih-server/
│ ├── base/ # Kustomize base — shared manifests
│ └── overlays/
│ └── prod/ # Production overlay (namespace, secrets, image tag)
├── argocd/ # ArgoCD Application definitions (one per app)
└── templates/
├── app/ # Template for new apps (copy this)
│ ├── base/
│ └── overlays/prod/
├── argocd/ # ArgoCD Application template
│ └── argocd-app.yaml
└── workflows/ # GitHub Actions templates for app repos
-
Copy template:
cp -r templates/app apps/<your-app>
-
Replace placeholders in all files under
apps/<your-app>/:<APP_NAME>— your app name (e.g.my-api)<NAMESPACE>— K8s namespace (e.g.my-api)<GH_USER_OR_ORG>— GitHub user/org owning the image<APP_PORT>— container port (e.g.8000)
-
Configure your app:
- Add env vars to
base/configmap.yaml - If app needs DB, copy
apps/mih-server/base/postgres.yamlas reference and uncomment inbase/kustomization.yaml
- Add env vars to
-
Create ArgoCD Application:
cp templates/argocd/argocd-app.yaml argocd/<your-app>-app.yaml
Replace placeholders in the new file.
-
Commit + push infra repo.
-
Apply secret manually on cluster (one-time, secret is NOT in git):
cp templates/app/overlays/prod/secret-example.yaml secret.yaml # local only # fill secret.yaml with real values kubectl create namespace <NAMESPACE> kubectl apply -f secret.yaml -n <NAMESPACE>
-
Done — no per-app
kubectl apply. The app-of-appsrootApplication (argocd/root-app.yaml) auto-discovers anyargocd/*-app.yamlonmainand syncs it. Just commit + push (step 5).First-time cluster setup only — apply the root once:
kubectl apply -f argocd/root-app.yaml
app repo infra repo (this) cluster
───────── ────────────────── ────────
push to main
│
▼
build image (CI)
│
▼
push to ghcr.io
│
▼
trigger workflow ───────► bump image tag in
overlays/prod/
kustomization.yaml
│
▼
commit + push
│
▼
ArgoCD detects ───────────► sync to cluster
In each app repo, copy templates/workflows/deploy-k8s.yml to .github/workflows/.
One job: builds the Docker image, pushes to GHCR, then bumps the tag in this repo
(ArgoCD syncs from there). Frontends uncomment the build-args block for their
build-time VITE_* vars.
Required in app repo settings (Settings → Secrets and variables → Actions):
- Secret
INFRA_APP_ID— GitHub App ID (see "GitHub App setup" below) - Secret
INFRA_APP_PRIVATE_KEY— full.pemfile contents - Variable
APP_NAME— folder name underapps/(e.g.mih-server)
The infra repo is updated by a GitHub App so commits don't rely on any individual user's PAT.
github.com/organizations/datasci4citizens/settings/apps → New GitHub App- Name:
infra-deployer - Webhook: disable
- Repository permissions → Contents: Read and write
- Where installable: "Only on this account"
- Create → note App ID + generate Private Key (downloads
.pem) - Install App on
server-infrastructurerepo - Share App ID and
.pemcontents with team members; each app repo stores them as secretsINFRA_APP_IDandINFRA_APP_PRIVATE_KEY
Secrets are NOT stored in git. Workflow:
secret-example.yaml(committed) — template showing required keyssecret.yaml(gitignored) — real values, applied manually to cluster once- ArgoCD manages everything else; references the existing
<APP_NAME>-secretin namespace
For production-grade secret management in git, look into Sealed Secrets or SOPS.
kubectl apply -k apps/<your-app>/overlays/prod