docker-compose.yml•4.28 kB
version: "3.9"
name: codegraph
volumes:
graph-data:
backups:
prometheus-data:
grafana-storage:
networks:
codegraph-net:
driver: bridge
services:
api:
build:
context: ../..
dockerfile: deployment/docker/Dockerfile
image: codegraph/api:latest
restart: unless-stopped
environment:
- APP_ENV=production
- RUST_LOG=info
- CODEGRAPH__SERVER__HOST=0.0.0.0
- CODEGRAPH__SERVER__PORT=8080
- CODEGRAPH__ROCKSDB__PATH=/var/lib/codegraph/graph.db
# Configure CORS origins (comma-separated) if needed
- CODEGRAPH__SECURITY__ALLOWED_ORIGINS=
ports:
- "8080:8080"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8080/health/ready >/dev/null 2>&1 || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 15s
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp:rw,nosuid,nodev,noexec,size=64m
ulimits:
nofile: 65536
cap_drop:
- ALL
user: "10001:10001"
volumes:
- graph-data:/var/lib/codegraph
# Mount config as read-only; override defaults if desired
- ../../config:/app/config:ro
networks:
- codegraph-net
# Resource limits (compose) + swarm-compatible deploy stanza
mem_limit: 1024m
cpus: "1.00"
deploy:
resources:
limits:
cpus: "1.00"
memory: 1024M
# Vector index maintenance sidecar (periodic rebuild/check)
vector-maintainer:
image: alpine:3.20
restart: unless-stopped
depends_on:
api:
condition: service_healthy
environment:
- API_BASE=http://api:8080
- PERIOD_SECONDS=21600 # 6 hours
entrypoint: ["/bin/sh", "/scripts/vector-maintainer.sh"]
healthcheck:
test: ["CMD-SHELL", "wget -qO- $${API_BASE}/health/live >/dev/null 2>&1 || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 20s
read_only: true
tmpfs:
- /tmp:rw,nosuid,nodev,noexec,size=16m
cap_drop: ["ALL"]
networks: [codegraph-net]
volumes:
- type: bind
source: ./scripts
target: /scripts
read_only: true
# RocksDB backups to a persistent backup volume
graph-backup:
image: alpine:3.20
restart: unless-stopped
depends_on:
api:
condition: service_started
environment:
- SRC_DIR=/var/lib/codegraph
- DEST_DIR=/backups
- INTERVAL_SECONDS=14400 # 4 hours
- RETAIN=10
entrypoint: ["/bin/sh", "/scripts/backup.sh"]
healthcheck:
test: ["CMD-SHELL", "test -d /backups || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
read_only: true
tmpfs:
- /tmp:rw,nosuid,nodev,noexec,size=16m
cap_drop: ["ALL"]
user: "10001:10001"
volumes:
- graph-data:/var/lib/codegraph:ro
- backups:/backups
- type: bind
source: ./scripts
target: /scripts
read_only: true
networks: [codegraph-net]
# Prometheus monitoring
prometheus:
image: prom/prometheus:v2.54.1
restart: unless-stopped
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention.time=7d
volumes:
- ../../prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
ports:
- "9090:9090"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:9090/-/healthy"]
interval: 30s
timeout: 5s
retries: 3
read_only: true
cap_drop: ["ALL"]
networks: [codegraph-net]
# Grafana dashboard
grafana:
image: grafana/grafana:11.1.3
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_DISABLE_LOGIN_FORM=true
volumes:
- grafana-storage:/var/lib/grafana
- ../../grafana-dashboard.json:/etc/grafana/provisioning/dashboards/default.json:ro
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/api/health"]
interval: 30s
timeout: 5s
retries: 3
read_only: true
cap_drop: ["ALL"]
networks: [codegraph-net]