version: '3.8' services: # 1. PostgreSQL Database Service postgres: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: strapi POSTGRES_USER: strapi POSTGRES_PASSWORD: strapi_password_9000 ports: - "9543:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U strapi -d strapi"] interval: 5s timeout: 5s retries: 5 networks: - citpl_net # 2. Strapi Headless CMS Service strapi-cms: build: context: ./strapi-cms dockerfile: Dockerfile restart: unless-stopped environment: DATABASE_CLIENT: postgres DATABASE_HOST: postgres DATABASE_PORT: 5432 DATABASE_NAME: strapi DATABASE_USERNAME: strapi DATABASE_PASSWORD: strapi_password_9000 DATABASE_SSL: "false" HOST: 0.0.0.0 PORT: 1337 APP_KEYS: "toBeModified1,toBeModified2,toBeModified3,toBeModified4" API_TOKEN_SALT: "tobemodifiedsalt" ADMIN_JWT_SECRET: "tobemodifiedadminjwt" TRANSFER_TOKEN_SALT: "tobemodifiedtransfertoken" JWT_SECRET: "tobemodifiedjwtsecret" ports: - "9337:1337" volumes: - strapi_uploads:/app/public/uploads depends_on: postgres: condition: service_healthy networks: - citpl_net # 3. Express Backend API Service backend: build: context: . dockerfile: Dockerfile.backend restart: unless-stopped environment: PORT: 3005 NODE_ENV: production STRAPI_URL: http://strapi-cms:1337 JWT_SECRET: dev-secret-key-12345 ADMIN_USERNAME: admin ADMIN_PASSWORD: admin123 CORS_ORIGIN: "*" ports: - "9305:3005" volumes: - backend_uploads:/app/server/uploads - backend_data:/app/server/data - strapi_uploads:/app/strapi-cms/public/uploads depends_on: - strapi-cms networks: - citpl_net # 4. Frontend Web App (Nginx SPA) frontend: build: context: . dockerfile: Dockerfile.frontend restart: unless-stopped expose: - "80" depends_on: - backend networks: - citpl_net networks: citpl_net: driver: bridge volumes: postgres_data: strapi_uploads: backend_uploads: backend_data: