docker-compose.dev.yml
Rama main · réplica de lectura del repositorio original.
# Guardyn Development Environment
# Start: docker compose -f docker-compose.dev.yml up -d
# Logs: docker compose -f docker-compose.dev.yml logs -f <service>
# Stop: docker compose -f docker-compose.dev.yml down
# Reset: docker compose -f docker-compose.dev.yml down -v
#
# E2EE is not configurable. The server never sees plaintext, in development as in
# production - it relays opaque bytes (docs/adr/ADR-0010-pure-relay-server.md). There is no
# switch to make debugging easier, because a switch is what invariant I-2 forbids.
version: "3.9"
x-rust-service: &rust-service
build:
context: ./backend
dockerfile: Dockerfile.dev
volumes:
- ./backend:/app
- cargo_cache:/usr/local/cargo/registry
- cargo_git:/usr/local/cargo/git
- target_cache:/app/target
environment: &rust-env
RUST_LOG: debug
RUST_BACKTRACE: 1
# JWT authentication (use GUARDYN_ prefix for consistency)
GUARDYN_AUTH__JWT_SECRET: "UNSAFE_DEV_SECRET_CHANGE_IN_PRODUCTION_32BYTES"
SCYLLA_CONSISTENCY: one
services:
# ═══════════════════════════════════════════════════════════════
# DATA LAYER
# ═══════════════════════════════════════════════════════════════
# NATS JetStream for real-time messaging
nats:
image: nats:2.10-alpine
container_name: guardyn-nats
command: ["-js", "-m", "8222"]
ports:
- "4222:4222" # Client connections
- "8222:8222" # HTTP monitoring
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8222/healthz"]
interval: 10s
timeout: 5s
retries: 5
redpanda:
image: redpandadata/redpanda:v24.2.1
container_name: guardyn-redpanda
command:
- redpanda start
- --mode dev-container
- --smp 1
- --memory 512M
- --overprovisioned
- --kafka-addr internal://0.0.0.0:9092,external://0.0.0.0:19092
- --advertise-kafka-addr internal://redpanda:9092,external://localhost:19092
- --schema-registry-addr internal://0.0.0.0:8081,external://0.0.0.0:18081
- --rpc-addr redpanda:33145
- --advertise-rpc-addr redpanda:33145
ports:
- "19092:19092" # Kafka API (external)
- "18081:18081" # Schema Registry (external)
- "8082:8082" # REST Proxy
- "9644:9644" # Admin API
volumes:
- redpanda_data:/var/lib/redpanda/data
healthcheck:
test: ["CMD", "rpk", "cluster", "health"]
interval: 10s
timeout: 5s
retries: 5
# PD (Placement Driver) for TiKV
pd:
image: pingcap/pd:v7.5.0
container_name: guardyn-pd
command:
- --name=pd
- --client-urls=http://0.0.0.0:2379
- --peer-urls=http://0.0.0.0:2380
- --advertise-client-urls=http://pd:2379
- --advertise-peer-urls=http://pd:2380
- --data-dir=/data/pd
ports:
- "2379:2379"
volumes:
- pd_data:/data/pd
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:2379/health"]
interval: 10s
timeout: 5s
retries: 5
tikv:
image: pingcap/tikv:v7.5.0
container_name: guardyn-tikv
command:
- --pd-endpoints=pd:2379
- --addr=0.0.0.0:20160
- --advertise-addr=tikv:20160
- --data-dir=/data/tikv
ports:
- "20160:20160"
volumes:
- tikv_data:/data/tikv
depends_on:
pd:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:20180/metrics"]
interval: 10s
timeout: 5s
retries: 5
scylladb:
image: scylladb/scylla:5.4
container_name: guardyn-scylladb
command: --smp 1 --memory 512M --developer-mode 1 --api-address 0.0.0.0
ports:
- "9042:9042" # CQL
- "10000:10000" # REST API
volumes:
- scylla_data:/var/lib/scylla
healthcheck:
test: ["CMD", "cqlsh", "-e", "SELECT now() FROM system.local"]
interval: 10s
timeout: 10s
retries: 10
minio:
image: minio/minio:latest
container_name: guardyn-minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: guardyn
MINIO_ROOT_PASSWORD: guardyn-dev-secret
ports:
- "9000:9000" # S3 API
- "9001:9001" # Console
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 10s
timeout: 5s
retries: 5
# MinIO initial bucket setup
minio-init:
image: minio/mc:latest
container_name: guardyn-minio-init
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
mc alias set myminio http://minio:9000 guardyn guardyn-dev-secret;
mc mb myminio/guardyn-media --ignore-existing;
mc mb myminio/guardyn-avatars --ignore-existing;
mc anonymous set download myminio/guardyn-avatars;
echo 'MinIO buckets initialized';
exit 0;
"
# ═══════════════════════════════════════════════════════════════
# EDGE LAYER
# ═══════════════════════════════════════════════════════════════
envoy:
image: envoyproxy/envoy:v1.31-latest
container_name: guardyn-envoy
volumes:
- ./infra/envoy/envoy-dev.yaml:/etc/envoy/envoy.yaml:ro
ports:
- "8080:8080" # API Gateway (gRPC routing)
- "8443:8443" # API Gateway TLS (if needed)
- "9901:9901" # Admin
depends_on:
- auth-service
- messaging-service
- presence-service
- media-service
- call-service
healthcheck:
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/localhost/9901' || exit 1"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
# ═══════════════════════════════════════════════════════════════
# BACKEND SERVICES (with hot reload via cargo-watch)
# ═══════════════════════════════════════════════════════════════
auth-service:
<<: *rust-service
container_name: guardyn-auth
command: cargo watch -x 'run --bin auth-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: auth-service
GUARDYN_HOST: "0.0.0.0"
GUARDYN_PORT: "50051"
GUARDYN_DATABASE__TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__SCYLLADB_NODES: scylladb:9042
GUARDYN_MESSAGING__NATS_URL: nats://nats:4222
# Redpanda's internal listener. localhost:19092 is the external listener, reachable
# only from the host - inside a container it resolves to the container itself.
REDPANDA_BROKERS: redpanda:9092
GUARDYN_OBSERVABILITY__OTLP_ENDPOINT: ""
GUARDYN_OBSERVABILITY__LOG_LEVEL: debug
ports:
- "50051:50051"
depends_on:
pd:
condition: service_healthy
tikv:
condition: service_started
redpanda:
condition: service_healthy
messaging-service:
<<: *rust-service
container_name: guardyn-messaging
command: cargo watch -x 'run --bin guardyn-messaging-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: messaging-service
GUARDYN_HOST: "0.0.0.0"
GUARDYN_PORT: "50052"
WEBSOCKET_PORT: "8081"
GUARDYN_DATABASE__TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__SCYLLADB_NODES: scylladb:9042
GUARDYN_MESSAGING__NATS_URL: nats://nats:4222
# Consumed by event_consumer.rs; see the note on auth-service.
REDPANDA_BROKERS: redpanda:9092
GUARDYN_OBSERVABILITY__OTLP_ENDPOINT: ""
GUARDYN_OBSERVABILITY__LOG_LEVEL: debug
ports:
- "50052:50052"
- "8081:8081" # WebSocket
depends_on:
pd:
condition: service_healthy
tikv:
condition: service_started
scylladb:
condition: service_healthy
nats:
condition: service_healthy
redpanda:
condition: service_healthy
presence-service:
<<: *rust-service
container_name: guardyn-presence
command: cargo watch -x 'run --bin guardyn-presence-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: presence-service
GUARDYN_HOST: "0.0.0.0"
GUARDYN_PORT: "50053"
GUARDYN_DATABASE__TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__SCYLLADB_NODES: scylladb:9042
GUARDYN_MESSAGING__NATS_URL: nats://nats:4222
GUARDYN_OBSERVABILITY__OTLP_ENDPOINT: ""
GUARDYN_OBSERVABILITY__LOG_LEVEL: debug
ports:
- "50053:50053"
depends_on:
pd:
condition: service_healthy
nats:
condition: service_healthy
media-service:
<<: *rust-service
container_name: guardyn-media
command: cargo watch -x 'run --bin guardyn-media-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: media-service
GUARDYN_HOST: "0.0.0.0"
GUARDYN_PORT: "50054"
# S3/MinIO configuration (MediaConfig::from_env() uses these)
S3_ENDPOINT: http://minio:9000
# Public endpoint for presigned URLs - use 10.0.2.2 for Android emulator
# This is the special IP that Android emulator uses to reach host machine
# The presigned URL signature MUST match the actual host the client connects to
S3_PUBLIC_ENDPOINT: http://10.0.2.2:9000
S3_ACCESS_KEY: guardyn
S3_SECRET_KEY: guardyn-dev-secret
S3_BUCKET_NAME: guardyn-media
S3_REGION: us-east-1
AWS_ACCESS_KEY_ID: guardyn
AWS_SECRET_ACCESS_KEY: guardyn-dev-secret
# TiKV configuration (code uses TIKV_PD_ENDPOINTS)
TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__SCYLLADB_NODES: scylladb:9042
GUARDYN_MESSAGING__NATS_URL: nats://nats:4222
GUARDYN_OBSERVABILITY__OTLP_ENDPOINT: ""
GUARDYN_OBSERVABILITY__LOG_LEVEL: debug
ports:
- "50054:50054"
depends_on:
minio:
condition: service_healthy
scylladb:
condition: service_healthy
pd:
condition: service_healthy
call-service:
<<: *rust-service
container_name: guardyn-call
command: cargo watch -x 'run --bin guardyn-call-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: call-service
LISTEN_ADDR: "0.0.0.0:50056"
SCYLLA_HOSTS: scylladb:9042
NATS_URL: nats://nats:4222
AUTH_SERVICE_URL: http://auth-service:50051
JWT_SECRET: "UNSAFE_DEV_SECRET_CHANGE_IN_PRODUCTION_32BYTES"
# WebSocket signaling port
SIGNALING_PORT: "8085"
# ICE servers for WebRTC (STUN/TURN)
# TURN_SERVER_URL: "turn:turn.yourdomain.com:3478"
# TURN_USERNAME: "turnuser"
# TURN_CREDENTIAL: "turnpass"
ports:
- "50056:50056" # gRPC
- "8085:8085" # WebSocket signaling
depends_on:
pd:
condition: service_healthy
scylladb:
condition: service_healthy
nats:
condition: service_healthy
auth-service:
condition: service_started
notification-service:
<<: *rust-service
container_name: guardyn-notification
command: cargo watch -x 'run --bin guardyn-notification-service'
environment:
<<: *rust-env
GUARDYN_SERVICE_NAME: notification-service
GUARDYN_HOST: "0.0.0.0"
GUARDYN_PORT: "50055"
GUARDYN_DATABASE__TIKV_PD_ENDPOINTS: pd:2379
GUARDYN_DATABASE__SCYLLADB_NODES: scylladb:9042
GUARDYN_MESSAGING__NATS_URL: nats://nats:4222
GUARDYN_OBSERVABILITY__OTLP_ENDPOINT: ""
GUARDYN_OBSERVABILITY__LOG_LEVEL: debug
# This service does not use the GUARDYN_* config loader - main.rs reads these two
# directly. Without them it binds 50054 and dials the Kubernetes ScyllaDB FQDN,
# which is why it failed to start under Compose.
LISTEN_ADDR: "0.0.0.0:50055"
SCYLLA_HOSTS: scylladb:9042
ports:
- "50055:50055"
depends_on:
pd:
condition: service_healthy
nats:
condition: service_healthy
scylladb:
condition: service_healthy
# ═══════════════════════════════════════════════════════════════
# OBSERVABILITY (optional - uncomment if needed)
# ═══════════════════════════════════════════════════════════════
# prometheus:
# image: prom/prometheus:v2.47.0
# container_name: guardyn-prometheus
# volumes:
# - ./infra/observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
# ports:
# - "9090:9090"
# command:
# - '--config.file=/etc/prometheus/prometheus.yml'
# - '--storage.tsdb.path=/prometheus'
# grafana:
# image: grafana/grafana:10.1.0
# container_name: guardyn-grafana
# environment:
# GF_SECURITY_ADMIN_PASSWORD: guardyn
# GF_AUTH_ANONYMOUS_ENABLED: "true"
# ports:
# - "3000:3000"
# volumes:
# - grafana_data:/var/lib/grafana
# ═══════════════════════════════════════════════════════════════
# REDPANDA CONSOLE (optional - for debugging)
# ═══════════════════════════════════════════════════════════════
redpanda-console:
image: redpandadata/console:v2.7.0
container_name: guardyn-redpanda-console
entrypoint: /bin/sh
command: -c "echo \"$$CONSOLE_CONFIG_FILE\" > /tmp/config.yml; /app/console"
environment:
CONFIG_FILEPATH: /tmp/config.yml
CONSOLE_CONFIG_FILE: |
kafka:
brokers: ["redpanda:9092"]
schemaRegistry:
enabled: true
urls: ["http://redpanda:8081"]
redpanda:
adminApi:
enabled: true
urls: ["http://redpanda:9644"]
ports:
- "8088:8080"
depends_on:
redpanda:
condition: service_healthy
volumes:
redpanda_data:
pd_data:
tikv_data:
scylla_data:
minio_data:
cargo_cache:
cargo_git:
target_cache:
# grafana_data:
networks:
default:
name: guardyn-dev