|
| 1 | +# Meridian demo deployment stack |
| 2 | +# |
| 3 | +# Services: |
| 4 | +# postgres - PostgreSQL 16 (internal only, not exposed to host) |
| 5 | +# meridian - Unified binary; starts after postgres is healthy |
| 6 | +# caddy - Reverse proxy; exposes 80/443, terminates TLS via Cloudflare Origin Certificate |
| 7 | +# |
| 8 | +# Usage: |
| 9 | +# cp deploy/demo/.env.demo.example /opt/meridian/.env |
| 10 | +# # Edit /opt/meridian/.env with actual values |
| 11 | +# docker compose --env-file /opt/meridian/.env -f /opt/meridian/docker-compose.yml up -d |
| 12 | +# |
| 13 | +# Directory layout expected on the host: |
| 14 | +# /opt/meridian/.env - Filled-in environment file |
| 15 | +# /opt/meridian/Caddyfile - Caddy configuration |
| 16 | +# /opt/meridian/certs/ - Cloudflare Origin Certificate files |
| 17 | +# origin-cert.pem |
| 18 | +# origin-key.pem |
| 19 | + |
| 20 | +services: |
| 21 | + postgres: |
| 22 | + image: postgres:16-alpine |
| 23 | + restart: unless-stopped |
| 24 | + environment: |
| 25 | + POSTGRES_USER: ${POSTGRES_USER:-meridian} |
| 26 | + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file} |
| 27 | + POSTGRES_DB: ${POSTGRES_DB:-meridian} |
| 28 | + volumes: |
| 29 | + - postgres_data:/var/lib/postgresql/data |
| 30 | + healthcheck: |
| 31 | + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-meridian} -d ${POSTGRES_DB:-meridian}"] |
| 32 | + interval: 5s |
| 33 | + timeout: 5s |
| 34 | + retries: 10 |
| 35 | + start_period: 10s |
| 36 | + # Not exposed to host — accessed only by meridian on the internal network |
| 37 | + |
| 38 | + meridian: |
| 39 | + image: ${MERIDIAN_IMAGE:-ghcr.io/meridianhub/meridian:demo} |
| 40 | + restart: unless-stopped |
| 41 | + depends_on: |
| 42 | + postgres: |
| 43 | + condition: service_healthy |
| 44 | + environment: |
| 45 | + # --- Application --- |
| 46 | + ENVIRONMENT: ${ENVIRONMENT:-demo} |
| 47 | + LOG_LEVEL: ${LOG_LEVEL:-info} |
| 48 | + |
| 49 | + # --- Database driver --- |
| 50 | + DB_DRIVER: postgres |
| 51 | + |
| 52 | + # --- Database URLs (all services share the same PostgreSQL instance in demo) --- |
| 53 | + DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 54 | + PLATFORM_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 55 | + CURRENT_ACCOUNT_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 56 | + FINANCIAL_ACCOUNTING_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 57 | + POSITION_KEEPING_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 58 | + PAYMENT_ORDER_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 59 | + PARTY_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 60 | + INTERNAL_BANK_ACCOUNT_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 61 | + MARKET_INFORMATION_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 62 | + REFERENCE_DATA_DATABASE_URL: postgres://${POSTGRES_USER:-meridian}:${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set in the env file}@postgres:5432/${POSTGRES_DB:-meridian}?sslmode=disable |
| 63 | + |
| 64 | + # --- Authentication --- |
| 65 | + AUTH_MODE: ${AUTH_MODE:-disabled} |
| 66 | + |
| 67 | + # --- Feature flags --- |
| 68 | + BILLING_ENABLED: ${BILLING_ENABLED:-false} |
| 69 | + REDIS_ENABLED: ${REDIS_ENABLED:-false} |
| 70 | + KAFKA_ENABLED: ${KAFKA_ENABLED:-false} |
| 71 | + |
| 72 | + # --- Multi-tenancy --- |
| 73 | + MASTER_TENANT_ID: ${MASTER_TENANT_ID:-meridian_master} |
| 74 | + |
| 75 | + # --- Connection pool --- |
| 76 | + DB_MAX_OPEN_CONNS: ${DB_MAX_OPEN_CONNS:-25} |
| 77 | + DB_MAX_IDLE_CONNS: ${DB_MAX_IDLE_CONNS:-5} |
| 78 | + DB_CONN_MAX_LIFETIME: ${DB_CONN_MAX_LIFETIME:-5m} |
| 79 | + DB_CONN_MAX_IDLE_TIME: ${DB_CONN_MAX_IDLE_TIME:-10m} |
| 80 | + # Note: The meridian image uses gcr.io/distroless/static-debian12 (no shell, |
| 81 | + # no wget), so a CMD-SHELL healthcheck cannot run. Health is monitored via |
| 82 | + # the gRPC health check service on port 50051. Caddy uses service_started |
| 83 | + # and retries upstream connections itself during meridian startup. |
| 84 | + # Not exposed to host — accessed only by caddy on the internal network |
| 85 | + |
| 86 | + caddy: |
| 87 | + image: caddy:2-alpine |
| 88 | + restart: unless-stopped |
| 89 | + depends_on: |
| 90 | + meridian: |
| 91 | + condition: service_started |
| 92 | + ports: |
| 93 | + - "80:80" |
| 94 | + - "443:443" |
| 95 | + volumes: |
| 96 | + - /opt/meridian/Caddyfile:/etc/caddy/Caddyfile:ro |
| 97 | + - /opt/meridian/certs:/etc/caddy/certs:ro |
| 98 | + - caddy_data:/data |
| 99 | + - caddy_config:/config |
| 100 | + |
| 101 | +volumes: |
| 102 | + postgres_data: |
| 103 | + caddy_data: |
| 104 | + caddy_config: |
0 commit comments