Blaster GitOps summary
Summary page for the Blaster GitOps series of runbooks. Blaster is a fun game I created last year as part of the AI for Everyone Series. I am using it now to demonstrate the full flow from local development on your workstation to Kubernetes dev and prod using GitLab, Kaniko and FluxCD. The same pattern can be applied to any other web app.
Blaster GitOps series
- Blaster GitOps summary - you are here
- Blaster repo and branches
- Dockerfile & GitLab CI
- Clerk authentication & user setup
- Google OAuth for Clerk
- Blaster prep for automation
- Dev app k8s manifests
- Dev flux sources & Kustomizations
- Dev image automation
- Dev SOPS & age
- Dev verification & troubleshooting
- Dev full runbook
- Prod overview
- Prod app k8s manifests and deployment
- Prod Flux GitOps and image automation
- Prod Cloudflare, Origin CA and tunnel routing
- Prod full runbook
- Post development branches
1. Context
Blaster is a small and fun Next.js + Phaser game that I am using as a vehicle to demonstrate my preferred on-prem GitOps flow.
The game itself is not important but for this series it's purpose is to:
- Generate real traffic through the toolchain.
- Exercise database, secrets, ingress and CI.
- Give you something you can actually open in a browser to see if changes worked.
The pattern matters more than the specific app. Anywhere you see “Blaster”, mentally substitute for “my web app”.
The reference stack looks like this:
- GitLab for source, CI and the container registry.
- Kaniko for building container images in the GitLab Kubernetes runner.
- FluxCD for GitOps reconciliation and image automation.
- SOPS + age for encrypted secrets.
- Ingress-NGINX + DNS for
blaster.reids.net.au(dev) andblaster.muppit.au(prod).
The detailed “how” lives in a set of focused runbooks. This summary page:
- Gives you a mental model of the flow.
- Points you to the right runbook for each task.
- States the expected outcomes, so you know when you are done.
2. High-level flow
From idea to production, using Blaster as the demo app, the path is:
- Local development on Mac
- Work on a
feature/*branch. - Use
.env.localand a local database. - Blaster is reachable at
http://localhost:3000afternpm run serveis executed.
- Work on a
- Push to GitLab
- Open a merge request into
develop. - GitLab CI runs
lintandtest.
- Open a merge request into
- Build images with Kaniko
- On
develop: buildsdev-YYYYMMDD.Ntags. - On
main: buildsprod-YYYYMMDD.Ntags.
- On
- Flux syncs k8s dev
GitRepository+Kustomizationfordevelop→k8s/dev.- Image automation updates the app
Deploymentwith the latestdev-tag.
- Test on k8s dev
- Blaster is reachable at
https://blaster.reids.net.auinside the network. - Fix issues by repeating steps 1–4.
- Blaster is reachable at
- Promote to k8s prod
- Merge
developintomainvia MR. - GitLab CI builds a
prod-YYYYMMDD.Ntag. - Flux
blaster-prodKustomization syncsk8s/prod.
- Merge
- Serve via Cloudflare
- TODO: Blaster prod to be configured so that blaster is reachable at
https://blaster.muppit.authrough the tunnel.
- TODO: Blaster prod to be configured so that blaster is reachable at
Everything is Git-first: no direct kubectl apply in Blaster namespaces. If you swap out Blaster for another app, the same flow applies.
3. Runbook map
Each detailed runbook focuses on a component of the system. Together, they describe the full flow using Blaster as the worked example:
| Area / Question | Runbook (to link) | What it covers |
|---|---|---|
| “How do I structure the repos?” | Blaster repo and branches | App vs infra repos, branches, environments, namespaces. |
| “How are images built and tagged?” | Dockerfile & GitLab CI | Dockerfile, Kaniko jobs, tag format for Flux image policies. |
| “What lives under k8s/dev and prod?” | App k8s manifests | Secrets, ConfigMaps, Deployments, Services, Ingress, SOPS. |
| “How does Flux see and deploy Blaster?” | Flux sources & Kustomizations | GitRepository + Kustomization setup for dev and prod. |
| “How do image policies & automation work?” | Image automation | ImageRepository, ImagePolicy, ImageUpdateAutomation. |
| “How do I encrypt and manage secrets?” | SOPS & age | SOPS config, age keys, Flux decryption setup. |
| “How do I verify everything is healthy?” | Verification & troubleshooting | Flux status, kubectl checks, common failure modes. |
| "How do I view the full dev runbook?" | Full runbook | Full runbook on one (long) page with every command and response |
If you are porting another app to this model, read them as “Blaster is my reference implementation”.
4. Expected outcomes
When all runbooks are followed successfully, using Blaster as the reference app:
- Repositories
games/blastercontains the app, Dockerfile,.gitlab-ci.ymlandk8s/overlays.fluxgitops/flux-configcontains Flux bootstrap config and ablasterfolder underclusters/my-cluster/.
- Branches and environments
developonly deploys to theblaster-devnamespace viak8s/dev.mainonly deploys to theblasternamespace viak8s/prod.- Production changes always flow through a merge request into
main.
- Images and tags
- GitLab Container Registry holds
dev-YYYYMMDD.Nandprod-YYYYMMDD.Ntags. - Flux image policies automatically track the latest
dev-tag for k8s dev.
- GitLab Container Registry holds
- Secrets and config
- All Kubernetes Secrets in Git are SOPS-encrypted.
- Flux uses the
sops-agesecret to decrypt them at apply time.
- Cluster state
- In
blaster-dev, the app and database pods are healthy, with working ingress atblaster.reids.net.au. - In
blaster, the prod app is healthy and reachable viablaster.muppit.au.
- In
If you later add another app, you can aim for the same outcomes with different names.
5. Quick start: minimal path through the runbooks
Use this when you are rebuilding Blaster from scratch on a new cluster, or when you are cloning the pattern for a new app.
- Create and push the app repo
- Initialise
games/blaster. - Push
main, createdevelop. - Add
.gitlab-ci.ymland Dockerfile.
- Initialise
- Configure GitLab CI
- Configure the Kubernetes runner.
- Add registry and Slack variables.
- Confirm
developandmainboth build images successfully.
- Add k8s manifests to the app repo
- Create
k8s/devandk8s/prodoverlays. - Add Secrets, ConfigMaps, Deployments, Services and Ingress.
- Encrypt Secrets with SOPS.
- Create
- Update the infra repo
- Add Flux GitRepository and Kustomization for Blaster dev (and later prod).
- Add image automation resources and SOPS policies.
- Bootstrap image automation
- Ensure Flux has a write-capable deploy key.
- Confirm ImageRepository / ImagePolicy and ImageUpdateAutomation become Ready.
- Verify dev
- Check Flux sources and Kustomizations.
- Confirm pods, Services and Ingress in
blaster-dev. - Play the game at
blaster.reids.net.au.
- Promote to prod
- Merge
developintomain. - Confirm prod image built and deployed to
blaster.muppit.au.
- Merge
For another app, the sequence is identical; only repo names, namespaces and hostnames change.
6. Guardrails to remember
When Blaster (or any other GitOps-managed app) is under Flux, do not hand-apply manifests in its namespaces. Git is the source of truth. Hotfixes belong in branches and merge requests.
Recommended practices that the detailed runbooks reinforce:
- Protect
mainanddevelop; require pipelines to pass before merge. - Keep secrets out of plain YAML and out of
.envfiles committed to Git. - Prefer small, focused commits over large “mystery refactors”.
- Use
flux reconcile ...andflux get ...for debugging instead of guessing.
7. Verification checklist
Use this checklist as you go configuring Blaster as the reference app:
-
games/blasterhask8s/devandk8s/proddirectories with akustomization.yamlin each. - GitLab CI builds and pushes images for commits on
developandmain. - Flux GitRepository and Kustomization for Blaster dev are Ready.
- ImageRepository, ImagePolicy and ImageUpdateAutomation are Ready.
- The
blaster-devnamespace has healthy app and database pods. -
https://blaster.reids.net.auserves the dev game inside the network. -
https://blaster.muppit.auserves the prod game via Cloudflare. - No-one runs
kubectl applydirectly in the Blaster namespaces.
Once all boxes are ticked, you have a fully functioning GitOps path for the Blaster demo game that you can re-use as a template for other applications.