agendapro/docker-compose.yml

157 lines
5.0 KiB
YAML

version: "3.8"
services:
# =============================================================
# TRAEFIK — Reverse Proxy & SSL (Let's Encrypt)
# =============================================================
traefik:
image: traefik:v2.11
command:
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.docker.swarmMode=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=admin@agendapro.com.br"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
ports:
- "80:80"
- "443:443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "traefik-certs:/letsencrypt"
networks:
- webproxy
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`traefik.agendapro.com.br`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
# =============================================================
# POSTGRESQL — Banco de Dados Compartilhado
# =============================================================
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: agendapro
POSTGRES_USER: agendapro_user
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
volumes:
- pgdata:/var/lib/postgresql/data
- ./database/init.sql:/docker-entrypoint-initdb.d/01-init.sql
networks:
- backend
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
# =============================================================
# AGENDAPRO APP — Sistema Principal (app.agendapro.com.br)
# =============================================================
agendapro:
image: agendapro-app:latest
build:
context: .
dockerfile: Dockerfile
environment:
DATABASE_URL: postgresql://agendapro_user:${DB_PASSWORD}@postgres:5432/agendapro
JWT_SECRET_FILE: /run/secrets/jwt_secret
NODE_ENV: production
secrets:
- jwt_secret
networks:
- webproxy
- backend
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
order: start-first
rollback_config:
parallelism: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.agendapro.rule=Host(`app.agendapro.com.br`)"
- "traefik.http.routers.agendapro.entrypoints=websecure"
- "traefik.http.routers.agendapro.tls.certresolver=letsencrypt"
- "traefik.http.services.agendapro.loadbalancer.server.port=3000"
- "traefik.http.services.agendapro.loadbalancer.healthcheck.path=/api/health"
- "traefik.http.services.agendapro.loadbalancer.healthcheck.interval=15s"
# =============================================================
# ADMIN PANEL — Gerenciador de Assinaturas (admin.agendapro.com.br)
# =============================================================
admin:
image: agendapro-admin:latest
build:
context: ./admin
dockerfile: Dockerfile
environment:
DATABASE_URL: postgresql://agendapro_user:${DB_PASSWORD}@postgres:5432/agendapro
JWT_SECRET_FILE: /run/secrets/jwt_secret
ADMIN_SECRET_FILE: /run/secrets/admin_secret
NODE_ENV: production
secrets:
- jwt_secret
- admin_secret
networks:
- webproxy
- backend
deploy:
replicas: 1
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
labels:
- "traefik.enable=true"
- "traefik.http.routers.admin.rule=Host(`admin.agendapro.com.br`)"
- "traefik.http.routers.admin.entrypoints=websecure"
- "traefik.http.routers.admin.tls.certresolver=letsencrypt"
- "traefik.http.services.admin.loadbalancer.server.port=3001"
# Proteção extra: Basic Auth no admin
- "traefik.http.routers.admin.middlewares=admin-auth"
- "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$xyz$$hashedpassword"
volumes:
pgdata:
traefik-certs:
networks:
webproxy:
driver: overlay
external: false
backend:
driver: overlay
internal: true
secrets:
db_password:
external: true
jwt_secret:
external: true
admin_secret:
external: true