version: '3.8' services: backend: build: context: . dockerfile: Dockerfile.backend container_name: dressed-for-success-backend hostname: backend expose: - "8000" environment: - DATABASE_URL=postgresql://postgres:postgres@postgres:5432/shop_db - DEBUG=0 - SECRET_KEY=${SECRET_KEY:-supersecretkey} - UPLOAD_DIRECTORY=/app/uploads - MEILISEARCH_URL=http://meilisearch:7700 - MEILISEARCH_KEY=dNmMmxymWpqTFyWSSFyg3xaGlEY6Pn7Ld-dyrnKRMzM depends_on: postgres: condition: service_healthy meilisearch: condition: service_started volumes: - ./backend/uploads:/app/uploads networks: app_network: aliases: - backend - fastapi restart: always healthcheck: test: ["CMD", "curl", "--fail", "http://localhost:8000/" ] interval: 10s timeout: 5s retries: 3 start_period: 15s frontend: build: context: . dockerfile: Dockerfile.frontend container_name: dressed-for-success-frontend hostname: frontend expose: - "3000" environment: - NEXT_PUBLIC_API_URL=https://${DOMAIN_NAME}/api - NEXT_PUBLIC_BASE_URL=https://${DOMAIN_NAME} - NODE_ENV=production volumes: - frontend_next_prod:/app/.next # сохраняем сборку в отдельном томе command: sh -c "npm run build && npm start" # явно запускаем сборку перед стартом depends_on: backend: condition: service_healthy networks: app_network: aliases: - frontend restart: always nginx: image: nginx:alpine container_name: dressed-for-success-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.prod.conf:/etc/nginx/conf.d/default.conf:ro - ./backend/uploads:/app/uploads:ro - ./certbot/conf:/etc/letsencrypt:ro - ./certbot/www:/var/www/certbot:ro depends_on: - frontend - backend networks: - app_network restart: always command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" certbot: image: certbot/certbot container_name: dressed-for-success-certbot volumes: - ./certbot/conf:/etc/letsencrypt - ./certbot/www:/var/www/certbot networks: - app_network depends_on: - nginx entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" postgres: image: postgres:15 container_name: dressed-for-success-db hostname: postgres environment: POSTGRES_DB: shop_db POSTGRES_USER: postgres POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} expose: - "5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 networks: app_network: aliases: - postgres restart: always redis: image: redis:alpine container_name: dressed-for-success-redis hostname: redis expose: - "6379" restart: always networks: app_network: aliases: - redis meilisearch: image: getmeili/meilisearch:latest container_name: dressed-for-success-meilisearch hostname: meilisearch expose: - "7700" environment: - MEILI_MASTER_KEY=dNmMmxymWpqTFyWSSFyg3xaGlEY6Pn7Ld-dyrnKRMzM - MEILI_NO_ANALYTICS=true - MEILI_ENV=production volumes: - meilisearch_data:/data.ms healthcheck: test: ["CMD", "wget", "--spider", "http://localhost:7700/health"] interval: 10s timeout: 5s retries: 3 start_period: 15s restart: always networks: app_network: aliases: - meilisearch networks: app_network: driver: bridge volumes: postgres_data: driver: local meilisearch_data: driver: local frontend_next_prod: driver: local