MJTHD
Blog
·1 min read

Shipping a site with Gitea CI and ArgoCD

The deploy pipeline behind this page: build once, sync from git, route two domains to one service.

kubernetesgitopsci

This site runs on a self-hosted Kubernetes cluster. The deploy is boring by design — boring is what you want at 2am.

The pipeline

A push to main runs a Gitea Actions workflow:

  1. install deps, build the Next.js app
  2. build a standalone container image
  3. tag it sha-<short> and latest, push to the registry

No image is built on the cluster. The build artifact is immutable and content- addressed by commit.

The sync

ArgoCD watches the k8s/ directory in this repo. When the deployment manifest changes — or a human bumps the image tag — ArgoCD reconciles the cluster to match git. selfHeal reverts manual drift; prune removes deleted resources.

syncPolicy:
  automated:
    prune: true
    selfHeal: true
  syncOptions:
    - CreateNamespace=true
    - ServerSideApply=true

Two domains, one service

Traefik terminates TLS for both taha.moujtahid.com and taha.mjthd.com, with certificates issued by cert-manager against Let's Encrypt. Both hosts point at the same ClusterIP service — there is exactly one running app.

The result: write code, push, and the change is live in a couple of minutes with a certificate that renews itself.