Files
k8s-starter-pack/docs/08-adding-new-apps.md
T

4.7 KiB

08 — Adding a new app

This is the payoff for the app-of-apps structure: adding something new is "drop a file here," not a special procedure.

The pattern

Every app in this repo is two things sitting side by side in apps/:

apps/
  demo.yaml     ← the Application (tells Argo CD where to look)
  demo/         ← the actual manifests (what gets deployed)

To add a new app called, say, whoami:

  1. Create apps/whoami/ and put its Kubernetes manifests in there — a Deployment, a Service, whatever it needs. Use apps/demo/ as a template for structure and comment style.

  2. Create apps/whoami.yaml, copied from apps/demo.yaml with the names changed: metadata.name, spec.source.repoURL (still this cluster's public Gitea repository — see docs/04-app-of-apps.md for why every Application needs this set individually, not inherited), spec.source.path (→ apps/whoami), and spec.destination.namespace.

  3. Commit and push both. That's it — no kubectl apply. The app-of-apps (already watching apps/ — see docs/04-app-of-apps.md) notices the new whoami.yaml, creates the whoami Application, which in turn deploys everything in apps/whoami/.

  4. Confirm: argocd app list should show whoami alongside demo, metallb, and longhorn.

If your new app needs storage, request it with a plain PersistentVolumeClaim and no storageClassName — Longhorn's chart set itself as the cluster's default StorageClass, so it's used automatically. See docs/06-longhorn.md.

If your new app needs hostNetwork, hostPath volumes, or privileged containers (uncommon, but real for things like storage or networking addons), Kubernetes' Pod Security Admission will reject it by default — see apps/metallb.yaml and apps/longhorn.yaml for the working pattern: an Application-level syncPolicy.managedNamespaceMetadata.labels opting just that namespace into the privileged profile. Ordinary apps like whoami never need this.

Manifest-based vs. Helm-based apps

apps/demo/ is plain Kubernetes manifests — no templating, nothing to render — which is why it's the easiest one to read start to finish while you're still learning what each field does.

An app's folder can be a Helm chart instead. Argo CD detects this automatically: if it finds a Chart.yaml at the source path, it treats that app as a Helm chart rather than plain manifests. This matters most when you want to pull in a third-party chart — a database, an ingress controller, anything with a public Helm chart already maintained by someone else — without copying their manifests into your repo by hand. You declare it as a dependency and let Helm (via Argo CD) resolve it.

You don't have to imagine this one — it's already running. apps/metallb/ is exactly this pattern, for real: its Chart.yaml declares a dependency on the upstream MetalLB chart, and it even goes a step further by also carrying its own templates (apps/metallb/templates/) for two custom resources that configure MetalLB once it's installed — useful to see if you ever need an app that's mostly someone else's chart but with a couple of your own resources layered on top. See docs/05-metallb.md for the full walkthrough, and apps/metallb.yaml for the matching Application — notice it's structurally identical to apps/demo.yaml; Argo CD figures out it's a Helm chart on its own from the presence of Chart.yaml, no new syntax required in the Application resource itself.

Ask Claude: "walk me through how I'd bring in [some real chart you have in mind] as a Helm-based app in this structure" whenever you're ready to try one of your own — apps/metallb/ is a real template to copy from.

If the new app has its own LoadBalancer Service (see docs/05-metallb.md), pick its address from the free addresses listed in docs/network.md, and add a row for it there once it's up — that file only stays useful if every app that gets an address shows up in it.

Checklist

  • New app's manifests live in apps/<name>/
  • New apps/<name>.yaml Application created, modeled on demo.yaml
  • repoURL set to this cluster's public Gitea repository, not left as a placeholder
  • Pushed to Git
  • argocd app list shows the new app, Synced/Healthy
  • If it has a LoadBalancer Service, its address is recorded in docs/network.md

Continue to docs/09-growing-up.md for what to add next as this cluster grows beyond a learning setup.