Docker Deployment
Deploy OpenPrime using Docker Compose for small to medium deployments.
Prerequisites​
- Docker Engine 24.0+
- Docker Compose v2.20+
- 4GB+ RAM available
- Valid SSL certificates (for production)
Production Docker Compose​
Create a production docker-compose.prod.yml:
version: '3.8'
services:
frontend:
image: openprime/frontend:latest
restart: unless-stopped
environment:
- NODE_ENV=production
- REACT_APP_API_URL=https://api.yourdomain.com
- REACT_APP_KEYCLOAK_URL=https://auth.yourdomain.com
- REACT_APP_KEYCLOAK_REALM=openprime
- REACT_APP_KEYCLOAK_CLIENT_ID=openprime-app
ports:
- "3000:80"
depends_on:
- backend
networks:
- openprime
backend:
image: openprime/backend:latest
restart: unless-stopped
environment:
- NODE_ENV=production
- PORT=3001
- DATABASE_URL=postgres://openprime:${DB_PASSWORD}@postgres:5432/openprime
- KEYCLOAK_URL=https://auth.yourdomain.com
- KEYCLOAK_REALM=openprime
- KEYCLOAK_CLIENT_ID=openprime-backend
- ENCRYPTION_KEY=${ENCRYPTION_KEY}
- LOG_LEVEL=info
- CORS_ORIGIN=https://yourdomain.com
ports:
- "3001:3001"
depends_on:
postgres:
condition: service_healthy
networks:
- openprime
postgres:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=openprime
- POSTGRES_PASSWORD=${DB_PASSWORD}
- POSTGRES_DB=openprime
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U openprime"]
interval: 10s
timeout: 5s
retries: 5
networks:
- openprime
keycloak:
image: quay.io/keycloak/keycloak:24.0
restart: unless-stopped
command: start
environment:
- KC_DB=postgres
- KC_DB_URL=jdbc:postgresql://keycloak-db:5432/keycloak
- KC_DB_USERNAME=keycloak
- KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD}
- KC_HOSTNAME=auth.yourdomain.com
- KC_PROXY=edge
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD}
ports:
- "8080:8080"
depends_on:
keycloak-db:
condition: service_healthy
networks:
- openprime
keycloak-db:
image: postgres:15-alpine
restart: unless-stopped
environment:
- POSTGRES_USER=keycloak
- POSTGRES_PASSWORD=${KEYCLOAK_DB_PASSWORD}
- POSTGRES_DB=keycloak
volumes:
- keycloak_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak"]
interval: 10s
timeout: 5s
retries: 5
networks:
- openprime
injecto:
image: openprime/injecto:latest
restart: unless-stopped
environment:
- LOG_LEVEL=info
ports:
- "8000:8000"
networks:
- openprime
volumes:
postgres_data:
keycloak_data:
networks:
openprime:
driver: bridge
Environment Variables​
Create a .env file:
# Database
DB_PASSWORD=your-secure-database-password
# Keycloak
KEYCLOAK_DB_PASSWORD=your-keycloak-db-password
KEYCLOAK_ADMIN_PASSWORD=your-admin-password
# Encryption (32-byte hex key)
ENCRYPTION_KEY=your-64-character-hex-encryption-key
# Domain
DOMAIN=yourdomain.com
Generate a secure encryption key:
openssl rand -hex 32
Reverse Proxy Configuration​
NGINX​
# /etc/nginx/sites-available/openprime
# Frontend
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
# API
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Keycloak
server {
listen 443 ssl http2;
server_name auth.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
Traefik​
# traefik/docker-compose.override.yml
services:
frontend:
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`yourdomain.com`)"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
backend:
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.yourdomain.com`)"
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
keycloak:
labels:
- "traefik.enable=true"
- "traefik.http.routers.auth.rule=Host(`auth.yourdomain.com`)"
- "traefik.http.routers.auth.tls.certresolver=letsencrypt"
Deployment Steps​
1. Prepare Server​
# Install Docker
curl -fsSL https://get.docker.com | sh
# Install Docker Compose
sudo apt install docker-compose-plugin
# Create deployment directory
mkdir -p /opt/openprime
cd /opt/openprime
2. Configure Environment​
# Copy configuration files
cp docker-compose.prod.yml docker-compose.yml
cp .env.example .env
# Edit environment variables
nano .env
3. Start Services​
# Pull latest images
docker compose pull
# Start services
docker compose up -d
# Check status
docker compose ps
# View logs
docker compose logs -f
4. Configure Keycloak​
- Access Keycloak Admin:
https://auth.yourdomain.com/admin - Create realm
openprime - Create clients for frontend and backend
- Configure users or identity federation
5. Verify Deployment​
# Health checks
curl https://yourdomain.com
curl https://api.yourdomain.com/health
curl https://auth.yourdomain.com/realms/openprime
Maintenance​
Backup​
# Backup databases
docker compose exec postgres pg_dump -U openprime openprime > backup.sql
docker compose exec keycloak-db pg_dump -U keycloak keycloak > keycloak-backup.sql
# Backup volumes
docker run --rm -v openprime_postgres_data:/data -v $(pwd):/backup \
alpine tar czf /backup/postgres-data.tar.gz /data
Update​
# Pull new images
docker compose pull
# Restart with new images
docker compose up -d
# Clean old images
docker image prune -f
Monitoring​
# Resource usage
docker stats
# Logs
docker compose logs -f --tail=100 backend
Troubleshooting​
Database Connection Issues​
# Check database is running
docker compose ps postgres
# Test connection
docker compose exec postgres psql -U openprime -c "SELECT 1"
Keycloak Issues​
# Check Keycloak logs
docker compose logs keycloak
# Verify database connection
docker compose exec keycloak-db psql -U keycloak -c "SELECT 1"
Certificate Issues​
# Verify certificates
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com