Skip to main content

Blaster GitOps summary

info

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

  1. Blaster GitOps summary - you are here
  2. Blaster repo and branches
  3. Dockerfile & GitLab CI
  4. Clerk authentication & user setup
  5. Google OAuth for Clerk
  6. Blaster prep for automation
  7. Dev app k8s manifests
  8. Dev flux sources & Kustomizations
  9. Dev image automation
  10. Dev SOPS & age
  11. Dev verification & troubleshooting
  12. Dev full runbook
  13. Prod overview
  14. Prod app k8s manifests and deployment
  15. Prod Flux GitOps and image automation
  16. Prod Cloudflare, Origin CA and tunnel routing
  17. Prod full runbook
  18. 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) and blaster.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:

  1. Local development on Mac
    • Work on a feature/* branch.
    • Use .env.local and a local database.
    • Blaster is reachable at http://localhost:3000 after npm run serve is executed.
  2. Push to GitLab
    • Open a merge request into develop.
    • GitLab CI runs lint and test.
  3. Build images with Kaniko
    • On develop: builds dev-YYYYMMDD.N tags.
    • On main: builds prod-YYYYMMDD.N tags.
  4. Flux syncs k8s dev
    • GitRepository + Kustomization for developk8s/dev.
    • Image automation updates the app Deployment with the latest dev- tag.
  5. Test on k8s dev
    • Blaster is reachable at https://blaster.reids.net.au inside the network.
    • Fix issues by repeating steps 1–4.
  6. Promote to k8s prod
    • Merge develop into main via MR.
    • GitLab CI builds a prod-YYYYMMDD.N tag.
    • Flux blaster-prod Kustomization syncs k8s/prod.
  7. Serve via Cloudflare
    • TODO: Blaster prod to be configured so that blaster is reachable at https://blaster.muppit.au through the tunnel.

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 / QuestionRunbook (to link)What it covers
“How do I structure the repos?”Blaster repo and branchesApp vs infra repos, branches, environments, namespaces.
“How are images built and tagged?”Dockerfile & GitLab CIDockerfile, Kaniko jobs, tag format for Flux image policies.
“What lives under k8s/dev and prod?”App k8s manifestsSecrets, ConfigMaps, Deployments, Services, Ingress, SOPS.
“How does Flux see and deploy Blaster?”Flux sources & KustomizationsGitRepository + Kustomization setup for dev and prod.
“How do image policies & automation work?”Image automationImageRepository, ImagePolicy, ImageUpdateAutomation.
“How do I encrypt and manage secrets?”SOPS & ageSOPS config, age keys, Flux decryption setup.
“How do I verify everything is healthy?”Verification & troubleshootingFlux status, kubectl checks, common failure modes.
"How do I view the full dev runbook?"Full runbookFull 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/blaster contains the app, Dockerfile, .gitlab-ci.yml and k8s/ overlays.
    • fluxgitops/flux-config contains Flux bootstrap config and a blaster folder under clusters/my-cluster/.
  • Branches and environments
    • develop only deploys to the blaster-dev namespace via k8s/dev.
    • main only deploys to the blaster namespace via k8s/prod.
    • Production changes always flow through a merge request into main.
  • Images and tags
    • GitLab Container Registry holds dev-YYYYMMDD.N and prod-YYYYMMDD.N tags.
    • Flux image policies automatically track the latest dev- tag for k8s dev.
  • Secrets and config
    • All Kubernetes Secrets in Git are SOPS-encrypted.
    • Flux uses the sops-age secret to decrypt them at apply time.
  • Cluster state
    • In blaster-dev, the app and database pods are healthy, with working ingress at blaster.reids.net.au.
    • In blaster, the prod app is healthy and reachable via blaster.muppit.au.

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.

  1. Create and push the app repo
    • Initialise games/blaster.
    • Push main, create develop.
    • Add .gitlab-ci.yml and Dockerfile.
  2. Configure GitLab CI
    • Configure the Kubernetes runner.
    • Add registry and Slack variables.
    • Confirm develop and main both build images successfully.
  3. Add k8s manifests to the app repo
    • Create k8s/dev and k8s/prod overlays.
    • Add Secrets, ConfigMaps, Deployments, Services and Ingress.
    • Encrypt Secrets with SOPS.
  4. Update the infra repo
    • Add Flux GitRepository and Kustomization for Blaster dev (and later prod).
    • Add image automation resources and SOPS policies.
  5. Bootstrap image automation
    • Ensure Flux has a write-capable deploy key.
    • Confirm ImageRepository / ImagePolicy and ImageUpdateAutomation become Ready.
  6. Verify dev
    • Check Flux sources and Kustomizations.
    • Confirm pods, Services and Ingress in blaster-dev.
    • Play the game at blaster.reids.net.au.
  7. Promote to prod
    • Merge develop into main.
    • Confirm prod image built and deployed to blaster.muppit.au.

For another app, the sequence is identical; only repo names, namespaces and hostnames change.

6. Guardrails to remember

warning

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 main and develop; require pipelines to pass before merge.
  • Keep secrets out of plain YAML and out of .env files committed to Git.
  • Prefer small, focused commits over large “mystery refactors”.
  • Use flux reconcile ... and flux get ... for debugging instead of guessing.

7. Verification checklist

Use this checklist as you go configuring Blaster as the reference app:

  • games/blaster has k8s/dev and k8s/prod directories with a kustomization.yaml in each.
  • GitLab CI builds and pushes images for commits on develop and main.
  • Flux GitRepository and Kustomization for Blaster dev are Ready.
  • ImageRepository, ImagePolicy and ImageUpdateAutomation are Ready.
  • The blaster-dev namespace has healthy app and database pods.
  • https://blaster.reids.net.au serves the dev game inside the network.
  • https://blaster.muppit.au serves the prod game via Cloudflare.
  • No-one runs kubectl apply directly 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.