version: '3.8'
services:
opencrates:
build:
context: .
target: runtime
container_name: opencrates-app
ports:
- "8080:8080"
- "9090:9090" environment:
- RUST_LOG=info
- OPENCRATES_HOST=0.0.0.0
- OPENCRATES_PORT=8080
- OPENCRATES_METRICS_PORT=9090
- OPENCRATES_DATABASE_URL=postgresql://opencrates:${POSTGRES_PASSWORD:-opencrates}@postgres:5432/opencrates
- OPENCRATES_REDIS_URL=redis://redis:6379
- OPENCRATES_SECRET_KEY=${OPENCRATES_SECRET_KEY:-your-secret-key-change-in-production}
- OPENAI_API_KEY=${OPENAI_API_KEY}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
volumes:
- opencrates_data:/app/data
- opencrates_logs:/app/logs
- ./config:/app/config:ro
- ./templates:/app/templates:ro
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
networks:
- opencrates-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 512M
postgres:
image: postgres:16-alpine
container_name: opencrates-db
environment:
- POSTGRES_DB=opencrates
- POSTGRES_USER=opencrates
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-opencrates}
- POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data
- ./migrations:/docker-entrypoint-initdb.d:ro
- ./config/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
ports:
- "5432:5432"
restart: unless-stopped
networks:
- opencrates-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U opencrates -d opencrates"]
interval: 15s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 1G
cpus: '0.5'
redis:
image: redis:7.2-alpine
container_name: opencrates-cache
ports:
- "6379:6379"
volumes:
- redis_data:/data
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
restart: unless-stopped
networks:
- opencrates-network
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 15s
timeout: 3s
retries: 3
deploy:
resources:
limits:
memory: 512M
cpus: '0.25'
prometheus:
image: prom/prometheus:v2.47.0
container_name: opencrates-prometheus
ports:
- "9091:9090"
volumes:
- prometheus_data:/prometheus
- ./config/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./config/prometheus/rules:/etc/prometheus/rules:ro
restart: unless-stopped
networks:
- opencrates-network
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=30d'
- '--web.enable-lifecycle'
- '--web.enable-admin-api'
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
interval: 30s
timeout: 10s
retries: 3
grafana:
image: grafana/grafana-oss:10.1.0
container_name: opencrates-grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_INSTALL_PLUGINS=grafana-piechart-panel
- GF_SERVER_ROOT_URL=http://localhost:3000
volumes:
- grafana_data:/var/lib/grafana
- ./config/grafana/provisioning:/etc/grafana/provisioning:ro
- ./config/grafana/dashboards:/var/lib/grafana/dashboards:ro
restart: unless-stopped
networks:
- opencrates-network
depends_on:
- prometheus
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
jaeger:
image: jaegertracing/all-in-one:1.49
container_name: opencrates-jaeger
ports:
- "16686:16686" - "14268:14268" - "14250:14250" - "6831:6831/udp" environment:
- COLLECTOR_OTLP_ENABLED=true
- COLLECTOR_ZIPKIN_HOST_PORT=:9411
volumes:
- jaeger_data:/tmp
networks:
- opencrates-network
restart: unless-stopped
elasticsearch:
image: elasticsearch:8.11.0
container_name: opencrates-elasticsearch
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms1g -Xmx1g
- xpack.security.enabled=false
- xpack.security.enrollment.enabled=false
- cluster.routing.allocation.disk.threshold_enabled=false
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
networks:
- opencrates-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
interval: 30s
timeout: 10s
retries: 5
deploy:
resources:
limits:
memory: 2G
kibana:
image: kibana:8.11.0
container_name: opencrates-kibana
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- SERVER_NAME=kibana
- SERVER_HOST=0.0.0.0
networks:
- opencrates-network
restart: unless-stopped
depends_on:
elasticsearch:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5601/api/status"]
interval: 30s
timeout: 10s
retries: 5
nginx:
image: nginx:1.25-alpine
container_name: opencrates-proxy
ports:
- "80:80"
- "443:443"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./config/nginx/conf.d:/etc/nginx/conf.d:ro
- ./config/ssl:/etc/nginx/ssl:ro
- nginx_logs:/var/log/nginx
restart: unless-stopped
networks:
- opencrates-network
depends_on:
- opencrates
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
opencrates-dev:
build:
context: .
target: development
container_name: opencrates-dev
volumes:
- .:/app
- cargo_cache:/usr/local/cargo/registry
- cargo_git_cache:/usr/local/cargo/git
working_dir: /app
networks:
- opencrates-network
profiles:
- development
environment:
- RUST_LOG=debug
- RUST_BACKTRACE=1
- OPENCRATES_DEV_MODE=true
command: cargo watch -x run
opencrates-test:
build:
context: .
target: testing
container_name: opencrates-test
volumes:
- .:/app
- cargo_cache:/usr/local/cargo/registry
- test_results:/app/test-results
working_dir: /app
networks:
- opencrates-network
profiles:
- testing
environment:
- RUST_LOG=debug
- RUST_BACKTRACE=1
- TEST_MODE=true
command: ./scripts/test-all.sh
mailhog:
image: mailhog/mailhog:v1.0.1
container_name: opencrates-mailhog
ports:
- "8025:8025" - "1025:1025" networks:
- opencrates-network
restart: unless-stopped
profiles:
- development
minio:
image: minio/minio:RELEASE.2023-10-07T15-07-38Z
container_name: opencrates-minio
command: server /data --console-address ":9001"
ports:
- "9000:9000" - "9001:9001" environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER:-minioadmin}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioadmin}
volumes:
- minio_data:/data
networks:
- opencrates-network
restart: unless-stopped
profiles:
- development
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
adminer:
image: adminer:4.8.1
container_name: opencrates-adminer
ports:
- "8081:8080"
networks:
- opencrates-network
restart: unless-stopped
profiles:
- development
depends_on:
- postgres
k6:
image: grafana/k6:0.46.0
container_name: opencrates-k6
volumes:
- ./scripts/k6:/scripts
- k6_results:/results
networks:
- opencrates-network
profiles:
- testing
depends_on:
- opencrates
command: run /scripts/load-test.js
volumes:
opencrates_data:
driver: local
opencrates_logs:
driver: local
postgres_data:
driver: local
redis_data:
driver: local
elasticsearch_data:
driver: local
prometheus_data:
driver: local
grafana_data:
driver: local
jaeger_data:
driver: local
minio_data:
driver: local
cargo_cache:
driver: local
cargo_git_cache:
driver: local
test_results:
driver: local
k6_results:
driver: local
nginx_logs:
driver: local
networks:
opencrates-network:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1