Auto-Deployment (GitOps) Deep Dive
How Auto-Deployment Works (GitOps)
Push an app → CI builds image → Flux detects new tag or PR with values → reconciles Helm/Kustomize to the cluster.
The Magic: FluxCD + Helm/Kustomize
What It Does
graph LR
A[App CI Build] -->|Push Image| B[GHCR]
B -->|Tag Update| C[Flux Image Automation]
C -->|Bump Values| D[Git Repo]
D -->|Source| E[Flux Controllers]
E -->|Reconcile| F[Cluster State]
App Packaging Examples
Helm values → K8s Deployment
Becomes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
template:
spec:
containers:
- name: web
image: myapp:latest
ports:
- containerPort: 3000
Service + Ingress
# values.yaml
ingress:
className: nginx
hosts:
- host: frontend.staging.dinetogether.co.uk
paths:
- path: /
pathType: Prefix
Creates Service + Ingress managed by the chart.
Volumes → PersistentVolumeClaims
Becomes:
# PersistentVolumeClaim
kind: PersistentVolumeClaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Auto-Deploy Workflow (Flux)
Trigger Mechanism
# In app repository workflow: build and push image
- name: Build and push
uses: docker/build-push-action@v6
with:
push: true
tags: ghcr.io/dine-together/frontend:sha-${{ github.sha }}
Auto-Deploy Steps
- Image built and pushed to GHCR
- Flux image automation updates Helm values (or a bot PR bumps tag)
- Flux reconciles and applies changes to the cluster
Packaging Guidance
Use golden Helm charts (Django API, Next.js frontend) and configure values for hostnames, resources, probes, and secrets.
Port Detection
# Explicit ports
if 'ports' in config:
# Use specified ports
# Implicit ports (Next.js/Node.js)
elif 'node' in image or 'next' in image:
ports = [{'containerPort': 3000}]
# Default web port
else:
ports = [{'containerPort': 80}]
Network Detection
Environment Management
Namespace Mapping
| Environment | Namespace | Domain |
|---|---|---|
| staging | dine-together-staging | *.staging.dinetogether.co.uk |
| production | dine-together-production | *.dinetogether.co.uk |
URL Generation
Security Features
- ImagePullSecrets for GHCR
- External Secrets or SOPS with Flux for secret management
Network Isolation
- Internal services: Default network only
- Public services: Default + Ingress network
Advanced Features
Resource Limits
Converts to:
Health Checks
# docker-compose.yml
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 30s
Becomes:
Replicas
Sets:
Debugging GitOps
View Applied Manifests
Check Conversion Logs
Force Reconcile
Customization
Skip Auto-Deployment
Pause a HelmRelease or Kustomization in Flux.
Custom Ingress Annotations
Override Detection
Best Practices
- Keep docker-compose.yml Simple
- One service per function
- Clear service names
-
Explicit configuration
-
Use Standard Ports
- 3000 for Node.js
- 8000 for Django
-
80 for nginx
-
Network Configuration
- Add
ingressnetwork for public services -
Keep databases on default network only
-
Secrets
- Use External Secrets or SOPS; avoid plaintext in Git
Next Steps
- Configure Secrets
- Set up Environments
- Learn Troubleshooting