version: '3.9' services: # ── Frontend (React PMS) ─────────────────────────────────────────────────── frontend: build: context: . dockerfile: Dockerfile container_name: hotelsync-frontend restart: unless-stopped networks: - hotelsync-net # ── CP (Control Panel) ───────────────────────────────────────────────────── cp: build: context: ./cp dockerfile: Dockerfile container_name: hotelsync-cp restart: unless-stopped networks: - hotelsync-net # ── API (Node.js + Fastify + PostgreSQL) ────────────────────────────────── api: build: context: ./backend dockerfile: Dockerfile container_name: hotelsync-api restart: unless-stopped env_file: .env environment: NODE_ENV: production PORT: "3000" DATABASE_URL: postgresql://${POSTGRES_USER:-hotelsync}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-hotelsync} REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379 JWT_SECRET: ${JWT_SECRET} CORS_ORIGINS: "https://app.hotelsync.ru,http://localhost:5173" depends_on: - postgres - redis networks: - hotelsync-net # ── PostgreSQL ───────────────────────────────────────────────────────────── postgres: image: postgres:16-alpine container_name: hotelsync-postgres restart: unless-stopped env_file: .env environment: POSTGRES_DB: ${POSTGRES_DB:-hotelsync} POSTGRES_USER: ${POSTGRES_USER:-hotelsync} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data networks: - hotelsync-net # ── Redis ────────────────────────────────────────────────────────────────── redis: image: redis:7-alpine container_name: hotelsync-redis restart: unless-stopped command: redis-server --requirepass ${REDIS_PASSWORD} volumes: - redis_data:/data networks: - hotelsync-net # ── Nginx (reverse proxy + SSL) ──────────────────────────────────────────── nginx: image: nginx:alpine container_name: hotelsync-nginx restart: unless-stopped ports: - "80:80" - "443:443" - "8080:8080" volumes: - ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./deploy/nginx/conf.d:/etc/nginx/conf.d:ro - certbot_www:/var/www/certbot:ro - certbot_certs:/etc/letsencrypt:ro depends_on: - frontend - cp - api networks: - hotelsync-net # ── Adminer (DB Web UI) ──────────────────────────────────────────────────── adminer: image: adminer:latest container_name: hotelsync-adminer restart: unless-stopped environment: ADMINER_DEFAULT_SERVER: postgres networks: - hotelsync-net # ── Certbot (SSL Let's Encrypt) ──────────────────────────────────────────── certbot: image: certbot/certbot container_name: hotelsync-certbot volumes: - certbot_www:/var/www/certbot - certbot_certs:/etc/letsencrypt entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" volumes: postgres_data: redis_data: certbot_www: certbot_certs: networks: hotelsync-net: driver: bridge