# Docker Compose for Coolify Deployment # Deploy all services in one run # # Usage in Coolify: # 1. Create new Docker Compose service # 2. Point to this file # 3. Set environment variables in Coolify UI # 4. Deploy services: # =========================================== # DATABASES # =========================================== postgres-backend: image: postgres:16-alpine container_name: placebo-postgres-backend restart: unless-stopped environment: POSTGRES_DB: placebo_backend_db POSTGRES_USER: placebo_user POSTGRES_PASSWORD: ${DATABASE_PASSWORD} volumes: - placebo-postgres-backend-data:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready'] interval: 5s timeout: 5s retries: 10 start_period: 30s networks: - placebo-internal postgres-cms: image: postgres:16-alpine container_name: placebo-postgres-cms restart: unless-stopped environment: POSTGRES_DB: placebo_cms_db POSTGRES_USER: placebo_user POSTGRES_PASSWORD: ${DATABASE_PASSWORD} volumes: - placebo-postgres-cms-data:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready'] interval: 5s timeout: 5s retries: 10 start_period: 30s networks: - placebo-internal # =========================================== # BACKEND (NestJS API) # =========================================== backend: build: context: ./backend dockerfile: Dockerfile container_name: placebo-backend restart: unless-stopped environment: NODE_ENV: production PORT: 3000 DATABASE_TYPE: postgres DATABASE_HOST: postgres-backend DATABASE_PORT: 5432 DATABASE_USERNAME: placebo_user DATABASE_PASSWORD: ${DATABASE_PASSWORD} DATABASE_NAME: placebo_backend_db DATABASE_SYNCHRONIZE: 'false' DATABASE_LOGGING: 'false' JWT_SECRET: ${JWT_SECRET} JWT_EXPIRATION: '86400' CORS_ORIGIN: https://placebo.mk,https://www.placebo.mk,https://app.placebo.mk STRAPI_URL: http://cms:1337 STRAPI_API_TOKEN: ${STRAPI_API_TOKEN} VAPID_SUBJECT: ${VAPID_SUBJECT:-mailto:contact@placebo.mk} VAPID_PUBLIC_KEY: ${VAPID_PUBLIC_KEY} VAPID_PRIVATE_KEY: ${VAPID_PRIVATE_KEY} depends_on: postgres-backend: condition: service_healthy healthcheck: test: ['CMD', 'node', '-e', "require('http').get('http://127.0.0.1:3000/api/v1/health', (r) => {if(r.statusCode !== 200) process.exit(1)})"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: - placebo-internal expose: - "3000" # =========================================== # CMS (Strapi) # =========================================== cms: build: context: ./cms/cms dockerfile: Dockerfile container_name: placebo-cms restart: unless-stopped environment: NODE_ENV: production HOST: 0.0.0.0 PORT: 1337 DATABASE_CLIENT: postgres DATABASE_HOST: postgres-cms DATABASE_PORT: '5432' DATABASE_NAME: placebo_cms_db DATABASE_USERNAME: placebo_user DATABASE_PASSWORD: ${DATABASE_PASSWORD} DATABASE_SSL: 'false' APP_KEYS: ${STRAPI_APP_KEYS} API_TOKEN_SALT: ${STRAPI_API_TOKEN_SALT} ADMIN_JWT_SECRET: ${STRAPI_ADMIN_JWT_SECRET} TRANSFER_TOKEN_SALT: ${STRAPI_TRANSFER_TOKEN_SALT} JWT_SECRET: ${STRAPI_JWT_SECRET} ENCRYPTION_KEY: ${STRAPI_ENCRYPTION_KEY} depends_on: postgres-cms: condition: service_healthy volumes: - placebo-cms-uploads:/app/public/uploads healthcheck: test: ['CMD', 'node', '-e', "require('http').get('http://127.0.0.1:1337/_health', (r) => {if(r.statusCode === 200 || r.statusCode === 204) process.exit(0); process.exit(1)})"] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - placebo-internal expose: - "1337" # =========================================== # FRONTEND (React) # =========================================== frontend: build: context: ./frontend dockerfile: Dockerfile args: VITE_API_URL: https://api.placebo.mk/api/v1 VITE_CMS_URL: https://cms.placebo.mk container_name: placebo-frontend restart: unless-stopped depends_on: - backend healthcheck: test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://127.0.0.1:80/'] interval: 30s timeout: 10s retries: 3 networks: - placebo-internal expose: - "80" # =========================================== # PWA (Progressive Web App) # =========================================== pwa: build: context: ./pwa dockerfile: Dockerfile args: VITE_API_URL: https://api.placebo.mk/api/v1 VITE_CMS_URL: https://cms.placebo.mk container_name: placebo-pwa restart: unless-stopped depends_on: - backend healthcheck: test: ['CMD', 'wget', '--no-verbose', '--tries=1', '--spider', 'http://127.0.0.1:80/'] interval: 30s timeout: 10s retries: 3 networks: - placebo-internal expose: - "80" # =========================================== # VOLUMES (Managed by Coolify) # =========================================== volumes: placebo-postgres-backend-data: driver: local placebo-postgres-cms-data: driver: local placebo-cms-uploads: driver: local # =========================================== # NETWORKS # =========================================== networks: placebo-internal: driver: bridge