Skip to content

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:

  1. Write code locally
  2. Test with docker-compose up
  3. Push to GitHub
  4. 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)
  • latest tag 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:

  1. Checks out the app repository
  2. Reads the docker-compose.yml
  3. Converts it to Kubernetes manifests using our Python script
  4. Applies manifests to the cluster
  5. 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 service
  • api.test.dinetogether.co.uk → Backend service
  • backend.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

  1. Developer Friendly: Use familiar docker-compose
  2. GitOps: Git as single source of truth
  3. Automatic: No manual deployment steps
  4. Scalable: Easy to add new services
  5. Portable: Can move to cloud K8s later
  6. Cost Effective: Single server for everything

Next Steps