Skip to Content

Docker Production Deployment

Overview

For self-hosted production deployments, the TEA Platform provides a production Docker Compose configuration (docker-compose.yml) that differs from the development setup in several ways:

  • Uses the pre-built image from GitHub Container Registry (ghcr.io) instead of building locally
  • Production-optimised Next.js build
  • Proper secret management via environment variables
  • Database persistence with named volumes
  • Health checks for both application and database

Azure Deployment

The official staging and production environments are hosted on Azure App Service and deployed automatically via GitHub Actions. This guide is for self-hosted deployments using Docker Compose.

Quick Start

1. Clone the Repository

git clone https://github.com/alan-turing-institute/AssurancePlatform.git cd AssurancePlatform

2. Create Production Environment File

cp .env.example .env

Edit .env with production values:

# Application NODE_ENV=production NEXTAUTH_URL=https://your-domain.com NEXTAUTH_SECRET=<generate-with-openssl-rand-base64-32> # Database DATABASE_URL=postgresql://tea:secure-password@db:5432/tea POSTGRES_USER=tea POSTGRES_PASSWORD=secure-password POSTGRES_DB=tea # GitHub OAuth (optional) GITHUB_APP_CLIENT_ID=your-client-id GITHUB_APP_CLIENT_SECRET=your-client-secret

3. Deploy

docker-compose -f docker-compose.yml up -d

This pulls the latest image from ghcr.io/alan-turing-institute/assuranceplatform:latest and starts the application with PostgreSQL.

Production Configuration

Container Names

ContainerServicePort
tea_appNext.js application3000
tea_postgresPostgreSQL database5432

Reverse Proxy

For production, place the application behind a reverse proxy for SSL termination:

Using nginx:

server { listen 443 ssl; server_name tea.example.com; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

Database Persistence

Database data is persisted via a named Docker volume (postgres_data). To use a bind mount instead:

volumes: postgres_data: driver: local driver_opts: type: none o: bind device: /data/postgres

Health Checks

The application includes a health check endpoint:

  • /api/health — Returns 200 when the application is ready

Updating

To update to a new version:

# Pull latest image docker-compose -f docker-compose.yml pull # Restart with new image docker-compose -f docker-compose.yml up -d

Or to build from source:

git pull origin main docker-compose -f docker-compose.yml up -d --build

Troubleshooting

View Logs

docker-compose -f docker-compose.yml logs -f tea_app

Database Connection Issues

  1. Verify DATABASE_URL is correct in your .env file
  2. Check database container is running: docker ps | grep tea_postgres
  3. Ensure network connectivity between containers

Application Not Starting

  1. Check logs for error messages
  2. Verify all required environment variables are set (NEXTAUTH_SECRET, DATABASE_URL)
  3. Ensure database migrations have run: docker exec tea_app npx prisma migrate deploy

Further Reading