Installing Argo CD — command reference
Companion to docs/03-installing-argocd.md
and docs/04-app-of-apps.md. Read those for the
why; this is the exact commands.
Run these once kubectl get nodes shows your node Ready (see
talos/README.md).
1. Install Argo CD
kubectl create namespace argocd
kubectl apply --server-side -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
--server-side matters here, not just as a nice-to-have: one of Argo CD's
CRDs (applicationsets.argoproj.io) is large enough that a normal
(client-side) kubectl apply fails outright — it tries to stash the whole
manifest into an annotation for its 3-way-merge bookkeeping, and that
annotation hits Kubernetes' size limit. Server-side apply has the API
server do that diffing instead, so this limit doesn't apply.
This is an imperative install: a plain kubectl apply of a manifest
bundle that the Argo CD project maintains, rather than a Helm chart or
operator. It's the officially documented quickstart path, and it means
Argo CD itself isn't part of your GitOps loop — you install it once, by
hand, and it then manages everything else declaratively. Bootstrapping
has to start somewhere outside the loop; this is that starting point.
The stable in that URL is a moving tag maintained by the Argo CD project
that always points at the latest stable release — convenient here, but not
reproducible: what it installs today may differ from what it installs in
six months. For a production setup, pin an explicit version instead, e.g.
.../v2.13.0/manifests/install.yaml — see releases
for current tags.
Wait for everything to come up:
kubectl -n argocd wait --for=condition=Available --timeout=300s deployment --all
2. Get the initial admin password
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d; echo
This secret is auto-generated on first install. Save the password somewhere; you'll change it in a moment.
3. Reach the UI and CLI
Argo CD doesn't expose itself outside the cluster by default. For this learning setup, forward its port to your machine:
kubectl -n argocd port-forward svc/argocd-server 8080:443
Leave that running in its own terminal. In another terminal:
argocd login localhost:8080 --username admin --password <password-from-above> --insecure
--insecure here means "skip TLS certificate verification" — the server's
certificate is self-signed by default and there's nothing on the other end
but your own port-forward, so this is fine for local access. It is not
something to carry into a setup reachable over the real network.
Open https://localhost:8080 in a browser to see the same thing visually.
Optional but recommended — replace the initial password:
argocd account update-password
4. Hand the cluster to Git
app-of-apps/app-of-apps.yaml is the one
manifest in this whole repo you apply by hand — everything after it, Argo
CD applies for you. Every Application manifest has its own repoURL
because child Applications do not inherit it from their parent. Verify they
all point at this cluster's public Gitea repository:
grep -R "repoURL:" argocd/app-of-apps apps/*.yaml
git ls-remote https://tea.ahmza.com/ahmza/k8s-starter-pack.git HEAD
The remote check must succeed without credentials. Commit and push any pending changes before continuing — child Applications read from Git, not your local disk. Then:
kubectl apply -f argocd/app-of-apps/app-of-apps.yaml
Watch it take over:
argocd app get app-of-apps
argocd app list
You should see app-of-apps sync, then demo, metallb, and longhorn
Applications appear underneath it, then sync themselves. See
docs/04-app-of-apps.md for what's happening
here and docs/checklist.md for the full guided
path.
5. Give the UI a real address (MetalLB)
Once metallb (above) is Synced/Healthy and you've configured its
address pool (see docs/05-metallb.md), you can
retire the port-forward from step 3 and give Argo CD's UI a permanent
address instead. This one change is applied directly, not through Git —
Argo CD's own install isn't managed by this repo's GitOps loop:
kubectl -n argocd patch svc argocd-server --type merge -p \
'{"spec":{"type":"LoadBalancer"},"metadata":{"annotations":{"metallb.io/loadBalancerIPs":"10.10.60.10"}}}'
kubectl -n argocd get svc argocd-server
Once EXTERNAL-IP shows 10.10.60.10, https://10.10.60.10 works
from routed networks — no port-forward required.