Files
bakery-ia/docker-compose.yml
2025-08-23 10:19:58 +02:00

1111 lines
31 KiB
YAML

# ================================================================
# OPTIMIZED DOCKER COMPOSE - NO ENVIRONMENT DUPLICATION
# Single source of truth: .env file only
# ================================================================
# ================================================================
# NETWORKS & VOLUMES (same as before)
# ================================================================
networks:
bakery-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
volumes:
auth_db_data:
training_db_data:
forecasting_db_data:
sales_db_data:
external_db_data:
tenant_db_data:
notification_db_data:
inventory_db_data:
recipes_db_data:
suppliers_db_data:
pos_db_data:
orders_db_data:
production_db_data:
redis_data:
rabbitmq_data:
prometheus_data:
grafana_data:
model_storage:
log_storage:
nominatim_data:
# ================================================================
# SERVICES - USING ONLY .env FILE
# ================================================================
services:
# ================================================================
# INFRASTRUCTURE - NO DUPLICATION
# ================================================================
redis:
image: redis:7-alpine
container_name: bakery-redis
restart: unless-stopped
# ONLY use environment substitution from .env
command: >
redis-server
--appendonly yes
--requirepass ${REDIS_PASSWORD}
--maxmemory ${REDIS_MAX_MEMORY:-512mb}
--databases 16
ports:
- "${REDIS_PORT}:6379"
volumes:
- redis_data:/data
networks:
bakery-network:
ipv4_address: 172.20.0.10
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 30s
timeout: 10s
retries: 3
rabbitmq:
image: rabbitmq:3.12-management-alpine
container_name: bakery-rabbitmq
restart: unless-stopped
# ONLY use environment substitution from .env
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}
- RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST}
ports:
- "${RABBITMQ_PORT}:5672"
- "${RABBITMQ_MANAGEMENT_PORT}:15672"
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
bakery-network:
ipv4_address: 172.20.0.11
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 30s
timeout: 10s
retries: 3
# ================================================================
# DATABASES - NO DUPLICATION
# ================================================================
auth-db:
image: postgres:15-alpine
container_name: bakery-auth-db
restart: unless-stopped
# ONLY reference .env variables
environment:
- POSTGRES_DB=${AUTH_DB_NAME}
- POSTGRES_USER=${AUTH_DB_USER}
- POSTGRES_PASSWORD=${AUTH_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- auth_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.20
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${AUTH_DB_USER} -d ${AUTH_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
training-db:
image: postgres:15-alpine
container_name: bakery-training-db
restart: unless-stopped
environment:
- POSTGRES_DB=${TRAINING_DB_NAME}
- POSTGRES_USER=${TRAINING_DB_USER}
- POSTGRES_PASSWORD=${TRAINING_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- training_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.21
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${TRAINING_DB_USER} -d ${TRAINING_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
forecasting-db:
image: postgres:15-alpine
container_name: bakery-forecasting-db
restart: unless-stopped
environment:
- POSTGRES_DB=${FORECASTING_DB_NAME}
- POSTGRES_USER=${FORECASTING_DB_USER}
- POSTGRES_PASSWORD=${FORECASTING_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- forecasting_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.22
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${FORECASTING_DB_USER} -d ${FORECASTING_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
sales-db:
image: postgres:15-alpine
container_name: bakery-sales-db
restart: unless-stopped
environment:
- POSTGRES_DB=${SALES_DB_NAME}
- POSTGRES_USER=${SALES_DB_USER}
- POSTGRES_PASSWORD=${SALES_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- sales_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.23
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SALES_DB_USER} -d ${SALES_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
external-db:
image: postgres:15-alpine
container_name: bakery-external-db
restart: unless-stopped
environment:
- POSTGRES_DB=${EXTERNAL_DB_NAME}
- POSTGRES_USER=${EXTERNAL_DB_USER}
- POSTGRES_PASSWORD=${EXTERNAL_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- external_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.24
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${EXTERNAL_DB_USER} -d ${EXTERNAL_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
tenant-db:
image: postgres:15-alpine
container_name: bakery-tenant-db
restart: unless-stopped
environment:
- POSTGRES_DB=${TENANT_DB_NAME}
- POSTGRES_USER=${TENANT_DB_USER}
- POSTGRES_PASSWORD=${TENANT_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- tenant_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.25
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${TENANT_DB_USER} -d ${TENANT_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
notification-db:
image: postgres:15-alpine
container_name: bakery-notification-db
restart: unless-stopped
environment:
- POSTGRES_DB=${NOTIFICATION_DB_NAME}
- POSTGRES_USER=${NOTIFICATION_DB_USER}
- POSTGRES_PASSWORD=${NOTIFICATION_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- notification_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.26
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${NOTIFICATION_DB_USER} -d ${NOTIFICATION_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
inventory-db:
image: postgres:15-alpine
container_name: bakery-inventory-db
restart: unless-stopped
environment:
- POSTGRES_DB=${INVENTORY_DB_NAME}
- POSTGRES_USER=${INVENTORY_DB_USER}
- POSTGRES_PASSWORD=${INVENTORY_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- inventory_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.27
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${INVENTORY_DB_USER} -d ${INVENTORY_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
recipes-db:
image: postgres:15-alpine
container_name: bakery-recipes-db
restart: unless-stopped
environment:
- POSTGRES_DB=${RECIPES_DB_NAME}
- POSTGRES_USER=${RECIPES_DB_USER}
- POSTGRES_PASSWORD=${RECIPES_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- recipes_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.28
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${RECIPES_DB_USER} -d ${RECIPES_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
suppliers-db:
image: postgres:15-alpine
container_name: bakery-suppliers-db
restart: unless-stopped
environment:
- POSTGRES_DB=${SUPPLIERS_DB_NAME}
- POSTGRES_USER=${SUPPLIERS_DB_USER}
- POSTGRES_PASSWORD=${SUPPLIERS_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- suppliers_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.29
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SUPPLIERS_DB_USER} -d ${SUPPLIERS_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
pos-db:
image: postgres:15-alpine
container_name: bakery-pos-db
restart: unless-stopped
environment:
- POSTGRES_DB=${POS_DB_NAME}
- POSTGRES_USER=${POS_DB_USER}
- POSTGRES_PASSWORD=${POS_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- pos_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.31
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POS_DB_USER} -d ${POS_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
orders-db:
image: postgres:15-alpine
container_name: bakery-orders-db
restart: unless-stopped
environment:
- POSTGRES_DB=${ORDERS_DB_NAME}
- POSTGRES_USER=${ORDERS_DB_USER}
- POSTGRES_PASSWORD=${ORDERS_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- orders_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.32
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${ORDERS_DB_USER} -d ${ORDERS_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
production-db:
image: postgres:15-alpine
container_name: bakery-production-db
restart: unless-stopped
environment:
- POSTGRES_DB=${PRODUCTION_DB_NAME}
- POSTGRES_USER=${PRODUCTION_DB_USER}
- POSTGRES_PASSWORD=${PRODUCTION_DB_PASSWORD}
- POSTGRES_INITDB_ARGS=${POSTGRES_INITDB_ARGS}
- PGDATA=/var/lib/postgresql/data/pgdata
volumes:
- production_db_data:/var/lib/postgresql/data
networks:
bakery-network:
ipv4_address: 172.20.0.33
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${PRODUCTION_DB_USER} -d ${PRODUCTION_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
# ================================================================
# LOCATION SERVICES (NEW SECTION)
# ================================================================
nominatim-db:
image: postgis/postgis:15-3.3 # Use PostGIS enabled PostgreSQL image
container_name: bakery-nominatim-db
restart: unless-stopped
environment:
- POSTGRES_DB=${NOMINATIM_DB_NAME}
- POSTGRES_USER=${NOMINATIM_DB_USER}
- POSTGRES_PASSWORD=${NOMINATIM_DB_PASSWORD}
- PGDATA=/var/lib/postgresql/data/pgdata
- POSTGRES_INITDB_ARGS="--auth-host=scram-sha-256" # Recommended for PostGIS
volumes:
- nominatim_db_data:/var/lib/postgresql/data
profiles:
- development
networks:
bakery-network:
ipv4_address: 172.20.0.30 # Assign a static IP for Nominatim to find it
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${NOMINATIM_DB_USER} -d ${NOMINATIM_DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
nominatim:
image: mediagis/nominatim:4.2 # A pre-built Nominatim image
container_name: bakery-nominatim
restart: unless-stopped
env_file: .env # Load environment variables from .env file
environment:
# Database connection details for Nominatim
- POSTGRES_HOST=nominatim-db
- POSTGRES_PORT=5432
- POSTGRES_USER=${NOMINATIM_DB_USER}
- POSTGRES_PASSWORD=${NOMINATIM_DB_PASSWORD}
- POSTGRES_DB=${NOMINATIM_DB_NAME}
- PBF_URL=${NOMINATIM_PBF_URL} # URL to your OpenStreetMap PBF data (e.g., Spain)
ports:
- "${NOMINATIM_PORT}:8080" # Expose Nominatim web interface
volumes:
- nominatim_data:/var/lib/nominatim # Persistent storage for Nominatim data and configuration
networks:
bakery-network:
ipv4_address: 172.20.0.120 # Assign a static IP for Nominatim service
depends_on:
nominatim-db:
condition: service_healthy # Ensure database is ready before Nominatim starts
# By default, mediagis/nominatim image will try to import data on first run
# if PBF_URL is set and the database is empty.
profiles:
- development
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/nominatim/status.php"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: ${NOMINATIM_MEMORY_LIMIT:-8G} # Nominatim is memory-intensive for import
cpus: '${NOMINATIM_CPU_LIMIT:-4}' # Adjust based on your system and data
# ================================================================
# MICROSERVICES - CLEAN APPROACH
# ================================================================
gateway:
build:
context: .
dockerfile: ./gateway/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/gateway:${IMAGE_TAG}
container_name: bakery-gateway
restart: unless-stopped
# ONLY load from .env file - no duplication
env_file: .env
ports:
- "${GATEWAY_PORT}:8000"
depends_on:
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.100
volumes:
- log_storage:/app/logs
- ./gateway:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
auth-service:
build:
context: .
dockerfile: ./services/auth/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/auth-service:${IMAGE_TAG}
container_name: bakery-auth-service
restart: unless-stopped
# ONLY load from .env file - no duplication
env_file: .env
ports:
- "${AUTH_SERVICE_PORT}:8000"
depends_on:
auth-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.101
volumes:
- log_storage:/app/logs
- ./services/auth:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
tenant-service:
build:
context: .
dockerfile: ./services/tenant/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/tenant-service:${IMAGE_TAG}
container_name: bakery-tenant-service
restart: unless-stopped
env_file: .env
ports:
- "${TENANT_SERVICE_PORT}:8000"
depends_on:
tenant-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.102
volumes:
- log_storage:/app/logs
- ./services/tenant:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
training-service:
build:
context: .
dockerfile: ./services/training/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/training-service:${IMAGE_TAG}
container_name: bakery-training-service
restart: unless-stopped
env_file: .env
ports:
- "${TRAINING_SERVICE_PORT}:8000"
depends_on:
training-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
sales-service:
condition: service_healthy
external-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.103
volumes:
- log_storage:/app/logs
- model_storage:/app/models
- ./services/training:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: ${TRAINING_MEMORY_LIMIT:-2G}
cpus: '${TRAINING_CPU_LIMIT:-1.5}'
forecasting-service:
build:
context: .
dockerfile: ./services/forecasting/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/forecasting-service:${IMAGE_TAG}
container_name: bakery-forecasting-service
restart: unless-stopped
env_file: .env
ports:
- "${FORECASTING_SERVICE_PORT}:8000"
depends_on:
forecasting-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
training-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.104
volumes:
- log_storage:/app/logs
- model_storage:/app/models
- ./services/forecasting:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
sales-service:
build:
context: .
dockerfile: ./services/sales/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/sales-service:${IMAGE_TAG}
container_name: bakery-sales-service
restart: unless-stopped
env_file: .env
ports:
- "${SALES_SERVICE_PORT}:8000"
depends_on:
sales-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.105
volumes:
- log_storage:/app/logs
- ./services/sales:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"]
interval: 30s
timeout: 10s
retries: 3
external-service:
build:
context: .
dockerfile: ./services/external/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/external-service:${IMAGE_TAG}
container_name: bakery-external-service
restart: unless-stopped
env_file: .env
ports:
- "${EXTERNAL_SERVICE_PORT}:8000"
depends_on:
external-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.106
volumes:
- log_storage:/app/logs
- ./services/external:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
notification-service:
build:
context: .
dockerfile: ./services/notification/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/notification-service:${IMAGE_TAG}
container_name: bakery-notification-service
restart: unless-stopped
env_file: .env
ports:
- "${NOTIFICATION_SERVICE_PORT}:8000"
depends_on:
notification-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.107
volumes:
- log_storage:/app/logs
- ./services/notification:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
alert-processor:
build:
context: .
dockerfile: ./services/alert_processor/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/alert-processor:${IMAGE_TAG}
restart: unless-stopped
env_file: .env
depends_on:
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
notification-service:
condition: service_healthy
networks:
- bakery-network
volumes:
- log_storage:/app/logs
- ./services/alert_processor:/app
- ./shared:/app/shared
deploy:
replicas: 2
resources:
limits:
memory: 512M
reservations:
memory: 256M
# No health check needed - this is a background worker service
# healthcheck:
# test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
# interval: 30s
# timeout: 10s
# retries: 3
inventory-service:
build:
context: .
dockerfile: ./services/inventory/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/inventory-service:${IMAGE_TAG}
container_name: bakery-inventory-service
restart: unless-stopped
env_file: .env
ports:
- "${INVENTORY_SERVICE_PORT}:8000"
depends_on:
inventory-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.108
volumes:
- log_storage:/app/logs
- ./services/inventory:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health/')"]
interval: 30s
timeout: 10s
retries: 3
recipes-service:
build:
context: .
dockerfile: ./services/recipes/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/recipes-service:${IMAGE_TAG}
container_name: bakery-recipes-service
restart: unless-stopped
env_file: .env
ports:
- "${RECIPES_SERVICE_PORT}:8000"
depends_on:
recipes-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
inventory-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.109
volumes:
- log_storage:/app/logs
- ./services/recipes:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3
suppliers-service:
build:
context: .
dockerfile: ./services/suppliers/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/suppliers-service:${IMAGE_TAG}
container_name: bakery-suppliers-service
restart: unless-stopped
env_file: .env
ports:
- "${SUPPLIERS_SERVICE_PORT}:8000"
depends_on:
suppliers-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
# Temporarily disabled due to health check issues
# inventory-service:
# condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.111
volumes:
- log_storage:/app/logs
- ./services/suppliers:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3
pos-service:
build:
context: .
dockerfile: ./services/pos/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/pos-service:${IMAGE_TAG}
container_name: bakery-pos-service
restart: unless-stopped
env_file: .env
ports:
- "${POS_SERVICE_PORT}:8000"
depends_on:
pos-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
sales-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.112
volumes:
- log_storage:/app/logs
- ./services/pos:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
orders-service:
build:
context: .
dockerfile: ./services/orders/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/orders-service:${IMAGE_TAG}
container_name: bakery-orders-service
restart: unless-stopped
env_file: .env
ports:
- "${ORDERS_SERVICE_PORT}:8000"
depends_on:
orders-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
inventory-service:
condition: service_healthy
suppliers-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.113
volumes:
- log_storage:/app/logs
- ./services/orders:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3
production-service:
build:
context: .
dockerfile: ./services/production/Dockerfile
args:
- ENVIRONMENT=${ENVIRONMENT}
- BUILD_DATE=${BUILD_DATE}
image: bakery/production-service:${IMAGE_TAG}
container_name: bakery-production-service
restart: unless-stopped
env_file: .env
ports:
- "${PRODUCTION_SERVICE_PORT}:8000"
depends_on:
production-db:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_healthy
auth-service:
condition: service_healthy
inventory-service:
condition: service_healthy
recipes-service:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.114
volumes:
- log_storage:/app/logs
- ./services/production:/app
- ./shared:/app/shared
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
interval: 30s
timeout: 10s
retries: 3
# ================================================================
# MONITORING - SIMPLE APPROACH
# ================================================================
prometheus:
image: prom/prometheus:v2.45.0
container_name: bakery-prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=${PROMETHEUS_RETENTION:-200h}'
- '--web.enable-lifecycle'
ports:
- "${PROMETHEUS_PORT}:9090"
volumes:
- ./infrastructure/monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus_data:/prometheus
networks:
bakery-network:
ipv4_address: 172.20.0.200
grafana:
image: grafana/grafana:10.0.0
container_name: bakery-grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_DEFAULT_TIMEZONE=${TIMEZONE}
- GF_SERVER_ROOT_URL=${GRAFANA_ROOT_URL}
ports:
- "${GRAFANA_PORT}:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./infrastructure/monitoring/grafana:/etc/grafana/provisioning:ro
networks:
bakery-network:
ipv4_address: 172.20.0.201
depends_on:
- prometheus
# ================================================================
# FRONTEND - CLEAN CONFIG
# ================================================================
dashboard:
build:
context: ./frontend
dockerfile: Dockerfile.development # Use the existing development Dockerfile
args:
- NODE_ENV=development
image: bakery/dashboard:${IMAGE_TAG:-latest}
container_name: bakery-dashboard
restart: unless-stopped
environment:
- NODE_ENV=development
- VITE_APP_TITLE=PanIA Dashboard
- VITE_APP_VERSION=1.0.0
ports:
- "${DASHBOARD_PORT:-3000}:3000"
depends_on:
gateway:
condition: service_healthy
networks:
bakery-network:
ipv4_address: 172.20.0.110
volumes:
- ./frontend:/app
- /app/node_modules # Exclude node_modules from bind mount
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
# ================================================================
# DEVELOPMENT TOOLS - OPTIONAL
# ================================================================
pgadmin:
image: dpage/pgadmin4:7.4
container_name: bakery-pgadmin
restart: unless-stopped
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
- PGADMIN_CONFIG_SERVER_MODE=False
ports:
- "${PGADMIN_PORT}:80"
volumes:
- ./infrastructure/pgadmin/servers.json:/pgadmin4/servers.json:ro
networks:
- bakery-network
profiles:
- development
- admin
redis-commander:
image: rediscommander/redis-commander:latest
container_name: bakery-redis-commander
restart: unless-stopped
environment:
- REDIS_HOSTS=local:redis:6379:0:${REDIS_PASSWORD}
- HTTP_USER=${REDIS_COMMANDER_USER}
- HTTP_PASSWORD=${REDIS_COMMANDER_PASSWORD}
ports:
- "${REDIS_COMMANDER_PORT}:8081"
networks:
- bakery-network
profiles:
- development
- admin
depends_on:
- redis