Docker
Production-ready Docker configurations using Docker Compose for containerizing and orchestrating all monorepo applications
Docker & Containerization
The monorepo includes production-ready Docker configurations for building and deploying all applications.
Overview
The Docker setup provides a robust, secure foundation for both development and production:
- Multi-stage Dockerfiles - Optimized images for web and API with minimal size
- Docker Compose - Orchestrate all services (web, API, database, Redis)
- Non-root Execution - Improved security by running containers as non-root users
- Health Checks - Services verify readiness before dependent services start
- Turbo Pruning - Faster builds with optimized dependency installation
- Development Environment - Simplified docker-compose for local development
Development Setup
For local development, use the docker-compose.yml file in the repository root:
docker-compose up -dThis starts the PostgreSQL database for development:
- PostgreSQL - localhost:5432
- Database - build-elevate-app
- User - postgres
- Password - password
Development Docker Compose Structure
The development setup includes:
services:
postgres:
image: postgres:16-alpine
container_name: build-elevate-postgres-dev
environment:
POSTGRES_DB: build-elevate-app
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
ports:
- 5432:5432
volumes:
- build-elevate-app_postgres_data_dev:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stoppedThe development docker-compose uses hardcoded credentials for convenience. Never use these credentials in production.
Common Development Commands
# Start PostgreSQL
docker-compose up -d
# Stop PostgreSQL
docker-compose down
# View logs
docker-compose logs -f postgres
# Connect to database directly
docker-compose exec postgres psql -U postgres -d build-elevate-app
# Remove volume and start fresh
docker-compose down -v && docker-compose up -dProduction Deployment
To build and run the full stack in production mode:
pnpm docker:prodThis will start:
- Web - http://localhost:3000
- API - http://localhost:4000
- PostgreSQL - localhost:5432
Production Configuration
Production deployments use docker-compose.prod.yml with optimized settings:
docker-compose -f docker-compose.prod.yml up -dProduction setup includes:
- Multi-stage optimized builds
- Minimal image sizes
- Non-root user execution
- Security hardening
- Health checks and monitoring
Key Files & Structure
| File | Purpose |
|---|---|
docker-compose.prod.yml | Production orchestration with optimized settings |
apps/web/Dockerfile.prod | Multi-stage build for Next.js frontend |
apps/api/Dockerfile.prod | Multi-stage build for Express backend |
Dockerfiles: Multi-Stage Builds
Both web and API Dockerfiles use a multi-stage build approach:
Stage 1: Builder
├─ Install dependencies
├─ Run build/compilation
└─ Generate artifacts
Stage 2: Runtime
├─ Copy only artifacts from builder
├─ Install runtime dependencies only
└─ Run applicationThis approach results in minimal production images by excluding build tools and dependencies.
Environment Configuration
Set environment variables for Docker containers in production (docker-compose.prod.yml):
environment:
DATABASE_URL: ${DATABASE_URL}
NODE_ENV: productionProduction values should be set via your deployment platform secrets.
Best Practices
Security
- Non-root Users - All containers run as non-root users (e.g.,
appuser:appuser) - Read-only Filesystems - Critical directories are read-only where possible
- Minimal Images - Use Alpine Linux base images (smaller attack surface)
- Secret Management - Never hardcode secrets; use environment variables or secret managers
Performance
- Layer Caching - Dockerfile layers are ordered for optimal caching
- Dependency Caching - Package installations happen before code changes
- Turbo Pruning - Only necessary dependencies are included in images
- Image Size - Multi-stage builds keep production images minimal
Reliability
- Health Checks - All services have health checks to verify readiness
- Depends On - Proper service dependencies ensure correct startup order
- Volume Management - Persistent data stored in named volumes
- Restart Policy - Services automatically restart on failure
Common Docker Commands
Build Images
# Build all images
docker-compose -f docker-compose.prod.yml build
# Build with no cache (fresh build)
docker-compose -f docker-compose.prod.yml build --no-cacheRun Services
# Start all services
docker-compose -f docker-compose.prod.yml up
# Start all services in background (detached mode)
docker-compose -f docker-compose.prod.yml up -d
# Start specific service
docker-compose -f docker-compose.prod.yml up apiMonitor & Debug
# View logs
docker-compose -f docker-compose.prod.yml logs
# Follow logs
docker-compose -f docker-compose.prod.yml logs -f
# Logs for specific service
docker-compose -f docker-compose.prod.yml logs -f api
# View running containers
docker-compose -f docker-compose.prod.yml ps
# Execute command in container
docker-compose -f docker-compose.prod.yml exec api shStop & Cleanup
# Stop all services
docker-compose -f docker-compose.prod.yml stop
# Stop and remove containers (keeps volumes)
docker-compose -f docker-compose.prod.yml down
# Remove everything including volumes (destructive)
docker-compose -f docker-compose.prod.yml down -v
# Remove unused images
docker image pruneTroubleshooting
Container Fails to Start
# Check logs
docker-compose -f docker-compose.prod.yml logs web
# Check health status
docker-compose -f docker-compose.prod.yml ps
# Restart service
docker-compose -f docker-compose.prod.yml restart webDatabase Connection Issues
# Check if PostgreSQL is healthy
docker-compose -f docker-compose.prod.yml ps postgres
# Connect to database
docker-compose -f docker-compose.prod.yml exec postgres psql -U postgres -d build-elevate
# View PostgreSQL logs
docker-compose -f docker-compose.prod.yml logs postgresClear Docker Resources
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune
# Remove all unused resources (images, containers, volumes)
docker system prune -aFor the complete docker-compose.prod.yml configuration, refer to the file in your repository root.
Next Steps
- Deploy with Docker - Use Docker Compose on your server or cloud provider
- Verify Services - Run
docker-compose -f docker-compose.prod.yml psto check all services are healthy - View Logs - Use
docker-compose -f docker-compose.prod.yml logsto monitor application behavior - Scale Services - Use Docker Compose replicas to run multiple instances (advanced)
For deployment guides, see the Deployment Documentation. To configure environment variables for containers, see Environment Variables.