Skip to main content

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​

  1. Access Keycloak Admin: https://auth.yourdomain.com/admin
  2. Create realm openprime
  3. Create clients for frontend and backend
  4. 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