Docker Compose Setup
This guide walks through a production-ready Docker Compose deployment of OpenCLM.
Repository Structure
openclm/
├── docker-compose.yml ← the main compose file
├── docker-compose.dev.yml ← development overrides
├── .env.example ← environment template
├── server/ ← API server source
├── src/ ← React frontend source
└── deploy/
├── nginx/ ← Nginx reverse proxy configs
└── caddy/ ← Caddy reverse proxy config
Step 1 — Clone and configure
git clone https://github.com/nxglabs/openclm.git
cd openclm
cp .env.example .env
Edit .env — see Environment Variables for all options.
Step 2 — docker-compose.yml
The default docker-compose.yml defines:
services:
db:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
keycloak:
image: quay.io/keycloak/keycloak:22
restart: unless-stopped
command: start
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://db/${POSTGRES_DB}
KC_DB_USERNAME: ${POSTGRES_USER}
KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
KC_HOSTNAME: ${APP_URL}
KEYCLOAK_ADMIN: ${KC_ADMIN_USER}
KEYCLOAK_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD}
depends_on:
db:
condition: service_healthy
api:
image: ghcr.io/nxglabs/openclm-api:latest
restart: unless-stopped
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}
JWT_SECRET: ${JWT_SECRET}
KEYCLOAK_URL: http://keycloak:8080
APP_URL: ${APP_URL}
depends_on:
db:
condition: service_healthy
app:
image: ghcr.io/nxglabs/openclm-app:latest
restart: unless-stopped
environment:
VITE_API_URL: ${APP_URL}/api
VITE_KEYCLOAK_URL: ${APP_URL}/auth
ports:
- "3000:3000"
depends_on:
- api
volumes:
pgdata:
Step 3 — Start services
docker compose up -d
Watch the logs to confirm all services start cleanly:
docker compose logs -f
Step 4 — Initialise the database
# Run Prisma migrations
docker compose exec api npx prisma migrate deploy
# Seed default roles and admin user
docker compose exec api npx prisma db seed
Step 5 — Set up the reverse proxy
Caddy (recommended)
openclm.yourdomain.com {
reverse_proxy /auth/* keycloak:8080
reverse_proxy /api/* api:4000
reverse_proxy /* app:3000
}
Run Caddy:
docker run -d -p 80:80 -p 443:443 \
-v $PWD/deploy/caddy/Caddyfile:/etc/caddy/Caddyfile \
caddy:2-alpine
Nginx
See /deploy/nginx/openclm.conf in the repository for a production Nginx config.
Step 6 — Verify
Navigate to https://openclm.yourdomain.com in your browser.
Log in with:
- Email:
[email protected] - Password:
Admin@1234(change immediately)
Updating OpenCLM
Pull the latest images and restart:
docker compose pull
docker compose up -d
docker compose exec api npx prisma migrate deploy
:::tip Zero-downtime updates For zero-downtime updates, use a rolling deployment strategy with Docker Swarm or Kubernetes instead of Docker Compose. :::
Backup & Restore
See Database Backup for Postgres backup procedures.