How DineTogether Infrastructure Works
Overview
The DineTogether infrastructure uses a GitOps workflow to automatically deploy applications from GitHub to a Kubernetes cluster running on a single server.
sequenceDiagram
participant Dev as Developer
participant GH as GitHub
participant GA as GitHub Actions
participant GHCR as Container Registry
participant Infra as k8s-infrastructure
participant K8s as K3s Cluster
participant User as End User
Dev->>GH: Push code to main
GH->>GA: Trigger build workflow
GA->>GA: Build Docker image
GA->>GHCR: Push image with tags
GA->>Infra: Trigger auto-deploy workflow
Infra->>GH: Checkout app repository
Infra->>Infra: Convert docker-compose.yml to K8s manifests
Infra->>K8s: Apply manifests (kubectl apply)
K8s->>K8s: Pull image from GHCR
K8s->>K8s: Create pods, services, ingress
User->>K8s: Access via HTTPS
Key Components
1. Developer Workflow
The developer experience is simple:
- Write code locally
- Test with
docker-compose up - Push to GitHub
- Automatic deployment happens!
No need to: - Write Kubernetes YAML files - Learn kubectl commands - Manage deployments manually - Configure CI/CD pipelines (already done!)
2. GitHub Actions Build Pipeline
Each repository has a .github/workflows/deploy.yml that:
- Builds Docker images on every push
- Tags images with:
- Branch name (e.g.,
main) - Git SHA (e.g.,
sha-abc123) latesttag for main branch- Pushes to GitHub Container Registry (GHCR)
- Triggers the deployment workflow
3. Auto-Deploy Workflow
The k8s-infrastructure repository contains the magic:
# Triggered by app repositories
on:
workflow_dispatch:
inputs:
repository:
description: 'Source repository'
required: true
environment:
description: 'Deployment environment'
required: true
This workflow:
- Checks out the app repository
- Reads the
docker-compose.yml - Converts it to Kubernetes manifests using our Python script
- Applies manifests to the cluster
- Reports deployment status
4. Docker Compose to Kubernetes Conversion
The compose-to-k8s.py script intelligently converts Docker Compose files:
| Docker Compose | Kubernetes |
|---|---|
services |
Deployments + Services |
ports |
Service ports + Ingress |
volumes |
PersistentVolumeClaims |
networks.ingress |
Ingress rules |
environment |
ConfigMaps/Env vars |
secrets |
Kubernetes Secrets |
deploy.replicas |
Deployment replicas |
Smart Detection
The converter automatically:
- Detects databases → Creates StatefulSets
- Detects web services → Creates Ingress rules
- Detects Next.js/Node.js → Sets correct ports
- Adds imagePullSecrets for GHCR
5. K3s Cluster
K3s is a lightweight Kubernetes that runs on a single server:
- Traefik ingress controller (built-in)
- Local-path storage provisioner
- CoreDNS for service discovery
- cert-manager for SSL certificates
6. Networking & Ingress
Traffic flow:
graph LR
A[Internet] -->|HTTPS| B[Traefik Ingress]
B -->|Route by hostname| C[Service]
C -->|Load balance| D[Pods]
B -->|frontend.test.*| E[Frontend Service]
B -->|api.test.*| F[Backend Service]
B -->|mobile.test.*| G[Mobile API Service]
Automatic subdomain routing:
frontend.test.dinetogether.co.uk→ Frontend serviceapi.test.dinetogether.co.uk→ Backend servicebackend.test.dinetogether.co.uk→ Backend admin
Security Features
1. Private Container Registry
- All images stored in private GHCR
- Requires authentication to pull
- Scoped to organization
2. Secrets Management
graph TD
A[GitHub Secrets] -->|DEPLOY_TOKEN| B[GitHub Actions]
B -->|Create K8s Secret| C[ghcr-secret]
C -->|Used by pods| D[Pull private images]
E[App Secrets] -->|Via GitHub| F[ConfigMaps/Secrets]
F -->|Mounted in pods| G[Application]
3. Network Isolation
- Default network for internal communication
- Ingress network for public-facing services
- No direct external access to databases
Deployment Environments
The infrastructure supports multiple environments:
| Environment | Namespace | Domain |
|---|---|---|
| Test/Staging | test-staging |
*.test.dinetogether.co.uk |
| Production | dine-together-production |
*.dinetogether.co.uk |
Monitoring & Debugging
Access deployment information:
# View pods
kubectl get pods -n test-staging
# View logs
kubectl logs -n test-staging deployment/frontend-web
# Check ingress
kubectl get ingress -n test-staging
# Describe issues
kubectl describe pod <pod-name> -n test-staging
Benefits of This Approach
- Developer Friendly: Use familiar docker-compose
- GitOps: Git as single source of truth
- Automatic: No manual deployment steps
- Scalable: Easy to add new services
- Portable: Can move to cloud K8s later
- Cost Effective: Single server for everything