Skip to content

Quick Start Guide

Deploy your application to DineTogether infrastructure in 5 minutes using GitOps!

Prerequisites

Before you start, make sure you have:

  • [ ] A GitHub repository in the dine-together organization
  • [ ] Docker installed locally
  • [ ] Access to the k8s-infrastructure repository
  • [ ] Basic understanding of Kubernetes concepts

Step 1: Build Your Container Image

Create a Dockerfile

Add a Dockerfile to your repository:

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["npm", "start"]
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000"]

Set Up GitHub Actions

Create .github/workflows/build.yml:

name: Build and Push

on:
  push:
    branches: [main]

env:
  REGISTRY: ghcr.io

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v4

      - name: Log in to GHCR
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ github.repository }}:latest
            ${{ env.REGISTRY }}/${{ github.repository }}:sha-${{ github.sha }}

Step 2: Deploy with Helm

Create HelmRelease

In the k8s-infrastructure repository, create:

clusters/staging/apps/your-app/helmrelease.yaml:

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: your-app
  namespace: staging
spec:
  interval: 5m
  chart:
    spec:
      chart: nextjs-app  # Use django-app for Django
      sourceRef:
        kind: GitRepository
        name: app-charts
        namespace: flux-system
      version: "*"
  values:
    image:
      repository: ghcr.io/dine-together/your-app
      tag: sha-YOUR_COMMIT_SHA  # Replace with actual SHA

    ingress:
      enabled: true
      className: nginx
      hosts:
        - host: your-app.staging.dinetogether.co.uk
          paths:
            - path: /
              pathType: Prefix

    service:
      port: 3000  # 8000 for Django

    resources:
      requests:
        cpu: 100m
        memory: 256Mi
      limits:
        cpu: 500m
        memory: 512Mi

Step 3: Deploy!

Push Your Changes

# In k8s-infrastructure repo
git add clusters/staging/apps/your-app/
git commit -m "Deploy your-app to staging"
git push origin main

Monitor Deployment

# Watch Flux sync
flux get kustomizations --watch

# Check your app
kubectl get pods -n staging
kubectl logs -n staging -l app=your-app

Step 4: Access Your App

Your application will be available at:

https://your-app.staging.dinetogether.co.uk

SSL certificates are automatically provisioned!

Common Patterns

Adding a Database

For PostgreSQL, add to your HelmRelease values:

postgresql:
  enabled: true
  auth:
    database: myapp
    username: myapp
    password: changeme  # Use secrets in production!

env:
  - name: DATABASE_URL
    value: postgresql://myapp:changeme@your-app-postgresql:5432/myapp

Adding Redis

redis:
  enabled: true
  auth:
    enabled: false  # Enable in production

env:
  - name: REDIS_URL
    value: redis://your-app-redis-master:6379

Using Secrets

Create a secret:

kubectl create secret generic your-app-secrets \
  --namespace=staging \
  --from-literal=API_KEY=secret-value

Reference in HelmRelease:

secretRefs:
  - name: your-app-secrets

Automated Image Updates

Enable automatic deployment when new images are pushed:

  1. Create ImageRepository:

    apiVersion: image.toolkit.fluxcd.io/v1beta2
    kind: ImageRepository
    metadata:
      name: your-app
      namespace: flux-system
    spec:
      image: ghcr.io/dine-together/your-app
      interval: 1m
    

  2. Create ImagePolicy:

    apiVersion: image.toolkit.fluxcd.io/v1beta2
    kind: ImagePolicy
    metadata:
      name: your-app
      namespace: flux-system
    spec:
      imageRepositoryRef:
        name: your-app
      policy:
        alphabetical:
          order: asc
      filterTags:
        pattern: '^sha-[a-f0-9]+'
    

  3. Add marker to HelmRelease:

    values:
      image:
        tag: sha-abc123  # {"$imagepolicy": "flux-system:your-app:tag"}
    

Troubleshooting

Pod Won't Start

# Check pod status
kubectl describe pod -n staging -l app=your-app

# Check events
kubectl get events -n staging

Image Pull Error

# Verify image exists
docker pull ghcr.io/dine-together/your-app:sha-abc123

# Check if repo is private (needs pull secret)

Application Errors

# View logs
kubectl logs -n staging deployment/your-app

# Get a shell
kubectl exec -it -n staging deployment/your-app -- sh

Next Steps

  • [ ] Set up production deployment
  • [ ] Configure monitoring (Prometheus metrics)
  • [ ] Add health checks
  • [ ] Set up CI/CD pipelines
  • [ ] Configure secrets management

Need Help?

Happy deploying! 🚀