Files
pos-system/deployments/local/docker-compose.yml

274 lines
10 KiB
YAML

version: '3.8'
# =============================================================================
# GoodGo Platform - Local Development Environment
# =============================================================================
#
# Prerequisites:
# 1. Copy env.local.example to .env.local and configure values
# 2. Ensure Docker and Docker Compose are installed
# 3. Get Neon PostgreSQL URL from https://console.neon.tech
#
# Start: docker-compose up -d
# Stop: docker-compose down
# Logs: docker-compose logs -f [service-name]
#
# Access Points:
# - Traefik Dashboard: http://localhost:8080
# - IAM Service: http://localhost/api/v1/auth (backward compatible)
# - IAM Service: http://localhost/api/v1/identity, /api/v1/access, /api/v1/governance
# - Web Admin: http://admin.localhost
# - Web Client: http://localhost
#
# =============================================================================
services:
# ===========================================================================
# SHARED INFRASTRUCTURE
# ===========================================================================
# Traefik - API Gateway and Reverse Proxy
traefik:
image: traefik:v3.3
container_name: traefik-local
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=goodgo-network"
- "--providers.file.directory=/etc/traefik/dynamic"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--log.level=${LOG_LEVEL:-INFO}"
- "--accesslog=true"
ports:
- "80:80" # HTTP
- "8080:8080" # Dashboard
volumes:
# EN: Use actual Docker Desktop socket path (not symlink)
# VI: Sử dụng đường dẫn socket thực của Docker Desktop (không phải symlink)
- ${HOME}/.docker/run/docker.sock:/var/run/docker.sock:ro
- ../../infra/traefik:/etc/traefik:ro
networks:
- microservices-network
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.localhost`)"
- "traefik.http.routers.traefik-dashboard.entrypoints=web"
- "traefik.http.routers.traefik-dashboard.service=api@internal"
# ===========================================================================
# BACKEND SERVICES
# ===========================================================================
# Storage Service .NET - File Storage Management
storage-service:
build:
context: ../../services/storage-service-net
dockerfile: Dockerfile
image: goodgo/storage-service-net:latest
container_name: storage-service-local
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:8080
# EN: Database - Neon PostgreSQL
# VI: Cơ sở dữ liệu - Neon PostgreSQL
- ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=storage_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
# EN: Storage - External MinIO
# VI: Storage - MinIO bên ngoài
- Storage__Provider=minio
- Storage__DefaultBucket=goodgo
- Storage__MinIO__Endpoint=167.114.174.113:9000
- Storage__MinIO__AccessKey=minioadmin
- Storage__MinIO__SecretKey=Velik@2026
- Storage__MinIO__UseSSL=false
# EN: IAM Service Communication
# VI: Giao tiếp IAM Service
- IamService__BaseUrl=http://iam-service-net:8080
- IamService__ServiceName=storage-service
# EN: Redis Cache
# VI: Cache Redis
- Redis__Host=167.114.174.113
- Redis__Port=6379
- Redis__Password=Velik@2026
ports:
- "5002:8080"
depends_on:
iam-service-net:
condition: service_healthy
traefik:
condition: service_started
networks:
- microservices-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- "traefik.enable=true"
- "traefik.http.routers.storage-service.rule=PathPrefix(`/api/v1/files`) || PathPrefix(`/api/v1/quota`)"
- "traefik.http.routers.storage-service.entrypoints=web"
- "traefik.http.services.storage-service.loadbalancer.server.port=8080"
- "traefik.http.services.storage-service.loadbalancer.healthcheck.path=/health/live"
- "traefik.http.services.storage-service.loadbalancer.healthcheck.interval=10s"
# Membership Service .NET - Membership Management
membership-service-net:
build:
context: ../../services/membership-service-net
dockerfile: Dockerfile
image: goodgo/membership-service-net:latest
container_name: membership-service-net-local
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://+:8080
# EN: Database - Neon PostgreSQL
# VI: Cơ sở dữ liệu - Neon PostgreSQL
- ConnectionStrings__DefaultConnection=Host=ep-holy-glitter-a4hongg7-pooler.us-east-1.aws.neon.tech;Port=5432;Database=membership_service;Username=neondb_owner;Password=npg_Ssfy6HKO0cXI;SSL Mode=Require
# EN: IAM Service Communication
# VI: Giao tiếp IAM Service
- IamService__BaseUrl=http://iam-service-net:8080
- IamService__ServiceName=membership-service
ports:
- "5003:8080"
depends_on:
iam-service-net:
condition: service_healthy
traefik:
condition: service_started
networks:
- microservices-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels:
- "traefik.enable=true"
- "traefik.http.routers.membership-service.rule=PathPrefix(`/api/v1/members`) || PathPrefix(`/api/v1/levels`) || PathPrefix(`/api/v1/memberships`) || PathPrefix(`/api/v1/subscriptions`)"
- "traefik.http.routers.membership-service.entrypoints=web"
- "traefik.http.services.membership-service.loadbalancer.server.port=8080"
- "traefik.http.services.membership-service.loadbalancer.healthcheck.path=/health/live"
- "traefik.http.services.membership-service.loadbalancer.healthcheck.interval=10s"
# IAM Service .NET - Identity and Access Management (Duende IdentityServer)
iam-service-net:
build:
context: ../../services/iam-service-net
dockerfile: Dockerfile
image: goodgo/iam-service-net:latest
container_name: iam-service-net-local
env_file:
- .env
environment:
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Development}
- ASPNETCORE_URLS=http://+:8080
# EN: Database - Neon PostgreSQL
# VI: Cơ sở dữ liệu - Neon PostgreSQL
- ConnectionStrings__DefaultConnection=${IAM_DATABASE_URL}
# EN: Redis Cache (external)
# VI: Cache Redis (bên ngoài)
- Redis__Host=${REDIS_HOST}
- Redis__Port=${REDIS_PORT}
- Redis__Password=${REDIS_PASSWORD}
- Redis__Database=${REDIS_DATABASE}
# EN: JWT Configuration
# VI: Cấu hình JWT
- Jwt__Secret=${JWT_SECRET}
- Jwt__Issuer=${JWT_ISSUER}
- Jwt__Audience=${JWT_AUDIENCE}
- Jwt__AccessTokenExpiryMinutes=${JWT_ACCESS_TOKEN_EXPIRY_MINUTES}
- Jwt__RefreshTokenExpiryDays=${JWT_REFRESH_TOKEN_EXPIRY_DAYS}
# EN: Features
# VI: Tính năng
- Features__SwaggerEnabled=${FEATURE_SWAGGER_ENABLED}
- Features__DetailedErrors=${FEATURE_DETAILED_ERRORS}
# EN: IdentityServer - Fixed issuer for inter-service communication
# VI: IdentityServer - Issuer cố định cho giao tiếp giữa các service
- IdentityServer__IssuerUri=http://iam-service
ports:
- "5001:8080"
depends_on:
traefik:
condition: service_started
networks:
- microservices-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
labels:
- "traefik.enable=true"
- "traefik.http.routers.iam-service-net.rule=PathPrefix(`/api/v1/iam`) || PathPrefix(`/api/v1/auth`) || PathPrefix(`/api/v1/users`) || PathPrefix(`/api/v1/roles`)"
- "traefik.http.routers.iam-service-net.entrypoints=web"
- "traefik.http.services.iam-service-net.loadbalancer.server.port=8080"
- "traefik.http.services.iam-service-net.loadbalancer.healthcheck.path=/health/live"
- "traefik.http.services.iam-service-net.loadbalancer.healthcheck.interval=10s"
# ===========================================================================
# OBSERVABILITY (Optional - Uncomment to enable)
# ===========================================================================
# Jaeger - Distributed Tracing
# jaeger:
# image: jaegertracing/all-in-one:1.47
# container_name: jaeger-local
# ports:
# - "16686:16686" # UI
# - "14268:14268" # Collector
# environment:
# - COLLECTOR_OTLP_ENABLED=true
# networks:
# - microservices-network
# restart: unless-stopped
# Prometheus - Metrics Collection
# prometheus:
# image: prom/prometheus:latest
# container_name: prometheus-local
# ports:
# - "9090:9090"
# volumes:
# - ../../infra/observability/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
# - prometheus_data:/prometheus
# networks:
# - microservices-network
# restart: unless-stopped
# Grafana - Metrics Visualization
# grafana:
# image: grafana/grafana:latest
# container_name: grafana-local
# ports:
# - "3001:3000"
# environment:
# - GF_SECURITY_ADMIN_PASSWORD=admin
# volumes:
# - grafana_data:/var/lib/grafana
# networks:
# - microservices-network
# restart: unless-stopped
# =============================================================================
# VOLUMES
# =============================================================================
volumes: {}
# =============================================================================
# NETWORKS
# =============================================================================
networks:
microservices-network:
driver: bridge
name: goodgo-network