Add the Sales CRM service through collaboration, sync architecture/registry docs, expose crm.torbatyar.ir, and include a production deploy script. Co-authored-by: Cursor <cursoragent@cursor.com>
288 lines
9.4 KiB
YAML
288 lines
9.4 KiB
YAML
# ============================================================
|
|
# SuperApp SaaS Platform - Docker Compose
|
|
# postgres, redis, keycloak, core-service, identity-access,
|
|
# celery-worker, celery-beat, frontend
|
|
# ============================================================
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
container_name: superapp_postgres
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
ports:
|
|
- "${POSTGRES_PORT:-5432}:5432"
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
- ./infrastructure/postgres/init-dbs.sql:/docker-entrypoint-initdb.d/02-init-dbs.sql
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- superapp_net
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: superapp_redis
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${REDIS_PORT:-6379}:6379"
|
|
volumes:
|
|
- redis_data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- superapp_net
|
|
|
|
keycloak:
|
|
image: quay.io/keycloak/keycloak:24.0
|
|
container_name: superapp_keycloak
|
|
restart: unless-stopped
|
|
command: start-dev --import-realm --features=token-exchange
|
|
environment:
|
|
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN:-admin}
|
|
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin}
|
|
KC_DB: postgres
|
|
KC_DB_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
|
|
KC_DB_USERNAME: ${POSTGRES_USER}
|
|
KC_DB_PASSWORD: ${POSTGRES_PASSWORD}
|
|
KC_HTTP_ENABLED: "true"
|
|
KC_HOSTNAME_STRICT: "false"
|
|
KC_PROXY: edge
|
|
KC_HOSTNAME: ${KEYCLOAK_HOSTNAME:-auth.torbatyar.ir}
|
|
KC_HOSTNAME_STRICT_HTTPS: ${KEYCLOAK_HOSTNAME_STRICT_HTTPS:-false}
|
|
JAVA_OPTS_KC_HEAP: "-Xms256m -Xmx512m"
|
|
ports:
|
|
- "8080:8080"
|
|
volumes:
|
|
- ./infrastructure/keycloak/realm:/opt/keycloak/data/import
|
|
- ./infrastructure/keycloak/themes:/opt/keycloak/themes
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
networks:
|
|
- superapp_net
|
|
|
|
core-service:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/core-service/Dockerfile.dev
|
|
container_name: superapp_core_service
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
ports:
|
|
- "8000:8000"
|
|
volumes:
|
|
- ./backend/core-service:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
keycloak:
|
|
condition: service_started
|
|
command: >
|
|
sh -c "alembic upgrade 0001_initial &&
|
|
alembic stamp head &&
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload"
|
|
networks:
|
|
- superapp_net
|
|
|
|
identity-access-service:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/services/identity-access/Dockerfile.dev
|
|
container_name: superapp_identity_service
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
DATABASE_URL: ${IDENTITY_DATABASE_URL}
|
|
DATABASE_URL_SYNC: ${IDENTITY_DATABASE_URL_SYNC}
|
|
IDENTITY_KEYCLOAK_CLIENT_ID: identity-access-service
|
|
KEYCLOAK_IDENTITY_CLIENT_SECRET: ${KEYCLOAK_IDENTITY_CLIENT_SECRET:-change-me-identity}
|
|
PLATFORM_ADMIN_MOBILES: ${PLATFORM_ADMIN_MOBILES:-}
|
|
KEYCLOAK_SERVER_URL: http://keycloak:8080
|
|
KEYCLOAK_PUBLIC_URL: ${KEYCLOAK_PUBLIC_URL:-http://localhost:8080}
|
|
CORE_SERVICE_URL: ${CORE_SERVICE_URL:-http://core-service:8000}
|
|
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}
|
|
ports:
|
|
- "8001:8001"
|
|
volumes:
|
|
- ./backend/services/identity-access:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
keycloak:
|
|
condition: service_started
|
|
core-service:
|
|
condition: service_started
|
|
command: >
|
|
sh -c "python scripts/ensure_db.py &&
|
|
alembic upgrade 0001_initial &&
|
|
alembic stamp head &&
|
|
(python scripts/enable_mobile_auth_client.py || true) &&
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8001 --reload"
|
|
networks:
|
|
- superapp_net
|
|
|
|
accounting-service:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/services/accounting/Dockerfile.dev
|
|
container_name: superapp_accounting_service
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
ACCOUNTING_DATABASE_URL: ${ACCOUNTING_DATABASE_URL}
|
|
ACCOUNTING_DATABASE_URL_SYNC: ${ACCOUNTING_DATABASE_URL_SYNC}
|
|
CORE_SERVICE_URL: ${CORE_SERVICE_URL:-http://core-service:8000}
|
|
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}
|
|
AUTH_REQUIRED: ${AUTH_REQUIRED:-true}
|
|
KEYCLOAK_SERVER_URL: ${KEYCLOAK_SERVER_URL:-http://keycloak:8080}
|
|
KEYCLOAK_PUBLIC_URL: ${KEYCLOAK_PUBLIC_URL:-http://localhost:8080}
|
|
KEYCLOAK_REALM: ${KEYCLOAK_REALM:-superapp}
|
|
JWT_VERIFY_SIGNATURE: ${JWT_VERIFY_SIGNATURE:-true}
|
|
ports:
|
|
- "8002:8002"
|
|
volumes:
|
|
- ./backend/services/accounting:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
core-service:
|
|
condition: service_started
|
|
command: >
|
|
sh -c "python scripts/ensure_db.py &&
|
|
alembic upgrade head &&
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8002 --reload"
|
|
networks:
|
|
- superapp_net
|
|
|
|
crm-service:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/services/crm/Dockerfile.dev
|
|
container_name: superapp_crm_service
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
environment:
|
|
CRM_DATABASE_URL: ${CRM_DATABASE_URL}
|
|
CRM_DATABASE_URL_SYNC: ${CRM_DATABASE_URL_SYNC}
|
|
CORE_SERVICE_URL: ${CORE_SERVICE_URL:-http://core-service:8000}
|
|
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost:3000}
|
|
AUTH_REQUIRED: ${AUTH_REQUIRED:-true}
|
|
KEYCLOAK_SERVER_URL: ${KEYCLOAK_SERVER_URL:-http://keycloak:8080}
|
|
KEYCLOAK_PUBLIC_URL: ${KEYCLOAK_PUBLIC_URL:-http://localhost:8080}
|
|
KEYCLOAK_REALM: ${KEYCLOAK_REALM:-superapp}
|
|
JWT_VERIFY_SIGNATURE: ${JWT_VERIFY_SIGNATURE:-true}
|
|
ports:
|
|
- "8003:8003"
|
|
volumes:
|
|
- ./backend/services/crm:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
core-service:
|
|
condition: service_started
|
|
command: >
|
|
sh -c "python scripts/ensure_db.py &&
|
|
alembic upgrade head &&
|
|
uvicorn app.main:app --host 0.0.0.0 --port 8003 --reload"
|
|
networks:
|
|
- superapp_net
|
|
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile.dev
|
|
container_name: superapp_frontend
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${FRONTEND_PORT:-3000}:3000"
|
|
environment:
|
|
NEXT_PUBLIC_BACKEND_URL: ${NEXT_PUBLIC_BACKEND_URL:-http://localhost:8000}
|
|
NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8000}
|
|
NEXT_PUBLIC_IDENTITY_API_URL: ${NEXT_PUBLIC_IDENTITY_API_URL:-http://localhost:8001}
|
|
NEXT_PUBLIC_KEYCLOAK_URL: ${NEXT_PUBLIC_KEYCLOAK_URL:-http://localhost:8080}
|
|
NEXT_PUBLIC_KEYCLOAK_REALM: ${NEXT_PUBLIC_KEYCLOAK_REALM:-superapp}
|
|
NEXT_PUBLIC_KEYCLOAK_CLIENT_ID: ${NEXT_PUBLIC_KEYCLOAK_CLIENT_ID:-superapp-frontend}
|
|
NEXT_PUBLIC_PLATFORM_BASE_DOMAIN: ${NEXT_PUBLIC_PLATFORM_BASE_DOMAIN:-torbatyar.ir}
|
|
NEXT_PUBLIC_ACCOUNTING_API_URL: ${NEXT_PUBLIC_ACCOUNTING_API_URL:-http://localhost:8002}
|
|
ACCOUNTING_SERVICE_URL: ${ACCOUNTING_SERVICE_URL:-http://accounting-service:8002}
|
|
# polling برای hot-reload پایدار روی volume mount ویندوز
|
|
WATCHPACK_POLLING: "true"
|
|
CHOKIDAR_USEPOLLING: "true"
|
|
volumes:
|
|
- ./frontend:/app
|
|
- frontend_node_modules:/app/node_modules
|
|
depends_on:
|
|
core-service:
|
|
condition: service_started
|
|
identity-access-service:
|
|
condition: service_started
|
|
networks:
|
|
- superapp_net
|
|
|
|
celery-worker:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/core-service/Dockerfile.dev
|
|
container_name: superapp_celery_worker
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
volumes:
|
|
- ./backend/core-service:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
postgres:
|
|
condition: service_healthy
|
|
command: celery -A app.workers.celery_app.celery_app worker --loglevel=INFO -Q default,core_events,notifications,webhooks
|
|
networks:
|
|
- superapp_net
|
|
|
|
celery-beat:
|
|
build:
|
|
context: .
|
|
dockerfile: backend/core-service/Dockerfile.dev
|
|
container_name: superapp_celery_beat
|
|
restart: unless-stopped
|
|
env_file:
|
|
- .env
|
|
volumes:
|
|
- ./backend/core-service:/app
|
|
- ./backend/shared-lib:/shared-lib
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
command: celery -A app.workers.celery_app.celery_app beat --loglevel=INFO
|
|
networks:
|
|
- superapp_net
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
frontend_node_modules:
|
|
|
|
networks:
|
|
superapp_net:
|
|
driver: bridge
|