Replace the 182-line inline schema in docker-compose.yml with a runner over packages/server/migrations, add 004 restoring the constraints and 64-bit counters the inline SQL carried, skip migrations already recorded in schema_versions, relabel the mount for SELinux, and drop the obsolete compose version key. Retarget the catalog contract test at the migration files. Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
177 lines
5.3 KiB
YAML
177 lines
5.3 KiB
YAML
|
|
services:
|
|
# ============================================================
|
|
# PostgreSQL
|
|
# ============================================================
|
|
postgres:
|
|
image: postgres:16-alpine
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-elydora}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-elydora-secret-change-me}
|
|
POSTGRES_DB: ${POSTGRES_DB:-elydora}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-elydora} -d ${POSTGRES_DB:-elydora}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# ============================================================
|
|
# Redis
|
|
# ============================================================
|
|
redis:
|
|
image: redis:7-alpine
|
|
restart: unless-stopped
|
|
command: redis-server --appendonly yes
|
|
volumes:
|
|
- redis_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# ============================================================
|
|
# MinIO (S3-compatible object storage)
|
|
# ============================================================
|
|
minio:
|
|
image: minio/minio:latest
|
|
restart: unless-stopped
|
|
command: server /data --console-address ":9001"
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-elydora}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-elydora-minio-secret-change-me}
|
|
volumes:
|
|
- minio_data:/data
|
|
ports:
|
|
- "9001:9001"
|
|
healthcheck:
|
|
test: ["CMD", "mc", "ready", "local"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# ============================================================
|
|
# MinIO init: creates the evidence bucket
|
|
# ============================================================
|
|
minio-init:
|
|
image: minio/mc:latest
|
|
depends_on:
|
|
minio:
|
|
condition: service_healthy
|
|
environment:
|
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER:-elydora}
|
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-elydora-minio-secret-change-me}
|
|
MINIO_BUCKET: ${MINIO_BUCKET:-elydora-evidence}
|
|
entrypoint: >
|
|
/bin/sh -c "
|
|
mc alias set local http://minio:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD};
|
|
mc mb --ignore-existing local/$${MINIO_BUCKET};
|
|
echo 'MinIO bucket initialized.';
|
|
"
|
|
restart: on-failure
|
|
|
|
# ============================================================
|
|
# DB migrate: applies packages/server/migrations
|
|
# ============================================================
|
|
db-migrate:
|
|
image: postgres:16-alpine
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
environment:
|
|
PGPASSWORD: ${POSTGRES_PASSWORD:-elydora-secret-change-me}
|
|
volumes:
|
|
- ./packages/server/migrations:/migrations:ro,z
|
|
entrypoint: ["sh", "-c"]
|
|
command:
|
|
- |
|
|
set -e
|
|
PSQL="psql -h postgres -U ${POSTGRES_USER:-elydora} -d ${POSTGRES_DB:-elydora}"
|
|
for file in /migrations/*.sql; do
|
|
version=$$(basename "$$file" | cut -d_ -f1 | sed 's/^0*//')
|
|
applied=$$($$PSQL -tAX -c "SELECT 1 FROM schema_versions WHERE version = $$version" 2>/dev/null || true)
|
|
if [ "$$applied" = "1" ]; then
|
|
echo "Skipping $$file (already applied)"
|
|
continue
|
|
fi
|
|
echo "Applying $$file"
|
|
$$PSQL -v ON_ERROR_STOP=1 -f "$$file"
|
|
done
|
|
|
|
api:
|
|
build:
|
|
context: ./packages/server
|
|
dockerfile: Dockerfile
|
|
restart: unless-stopped
|
|
env_file: .env
|
|
ports:
|
|
- "${PORT:-8787}:8787"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
minio:
|
|
condition: service_healthy
|
|
db-migrate:
|
|
condition: service_completed_successfully
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "wget -qO- http://localhost:8787/v1/health || exit 1"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# ============================================================
|
|
# Worker (queue consumer)
|
|
# ============================================================
|
|
worker:
|
|
build:
|
|
context: ./packages/server
|
|
dockerfile: Dockerfile
|
|
restart: unless-stopped
|
|
command: ["node", "dist/worker.js"]
|
|
env_file: .env
|
|
depends_on:
|
|
api:
|
|
condition: service_healthy
|
|
|
|
# ============================================================
|
|
# Scheduler (epoch scheduler)
|
|
# ============================================================
|
|
scheduler:
|
|
build:
|
|
context: ./packages/server
|
|
dockerfile: Dockerfile
|
|
restart: unless-stopped
|
|
command: ["node", "dist/scheduler.js"]
|
|
env_file: .env
|
|
depends_on:
|
|
api:
|
|
condition: service_healthy
|
|
|
|
# ============================================================
|
|
# Console (Next.js frontend)
|
|
# ============================================================
|
|
console:
|
|
build:
|
|
context: .
|
|
dockerfile: packages/console/Dockerfile
|
|
args:
|
|
NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8787}
|
|
restart: unless-stopped
|
|
environment:
|
|
NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8787}
|
|
ports:
|
|
- "3000:3000"
|
|
depends_on:
|
|
api:
|
|
condition: service_healthy
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
minio_data:
|