version: '3.8' services: app: build: context: . dockerfile: Dockerfile ports: - "3000:3000" env_file: .env environment: DATABASE_URL: ${DATABASE_URL} DB_HOST: ${DB_HOST} DB_PORT: ${DB_PORT} DB_NAME: ${DB_NAME} DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} SECRET_KEY_BASE: ${SECRET_KEY_BASE} RAILS_ENV: ${RAILS_ENV:-development} # Fuso do SISTEMA OPERACIONAL dentro do container (o do Rails vem do # config.time_zone). Já fixado no Dockerfile; repetido aqui para dar o # ajuste sem rebuild — basta TZ=... no .env. Ver deploy/ntp-seguro.sh: # a HORA em si é do host, isto aqui só define o fuso de leitura. TZ: ${TZ:-America/Sao_Paulo} volumes: - ".:/app" - "bundle_cache:/usr/local/bundle" # Todo o boot (migrations, cron, Puma) mora em bin/docker-boot, com o # motivo de cada passo comentado lá. Ficava aqui como uma linha só de # `bash -c`, ilegível e impossível de depurar quando um passo falhava. # # `bash` explícito de propósito, em vez de chamar o script direto: a pasta # do projeto vive num share do NAS e o BIT DE EXECUÇÃO se perde ao copiar # por SMB/File Station. Sem isto, o deploy morreria com um # "permission denied" que não tem nada a ver com o script. command: ["bash", "bin/docker-boot"] # `unless-stopped`: sobe sozinho depois de queda do processo, de reboot do # servidor e de `docker compose up`, e SÓ fica parado se alguém der # `docker compose stop/down` explicitamente. Como o bin/docker-boot roda # `db:prepare` no começo, isso já entrega a migration automática a cada # restart — não existe passo manual depois do deploy. # # Escolhido em vez de `always` porque `always` reergue o container até # depois de um `stop` deliberado (num reboot do servidor), tirando do # operador a chance de deixar o sistema fora do ar de propósito. restart: unless-stopped # O banco PostgreSQL já existe externamente. # Configure DB_HOST no .env com o IP/hostname do seu servidor PostgreSQL. # # SEM `depends_on: whatsapp` de propósito: o Rails não precisa da ponte para # subir nem para funcionar — sem ela, a tela mostra "desconectado" e o envio # de WhatsApp registra falha no log de envios. Declarar a dependência faria # um problema no container do WhatsApp respingar no sistema inteiro. # Ponte com o WhatsApp (Baileys, sessão pareada por QR). Container separado # porque não existe biblioteca Ruby que fale o protocolo do WhatsApp Web — e # porque isolar a sessão evita que uma queda dela derrube o Puma. # # ⚠️ A porta NÃO é publicada de propósito: quem alcança é só o container do # Rails, pela rede interna do compose. Publicar exporia um endpoint que # manda mensagem em nome da empresa. whatsapp: build: context: ./whatsapp dockerfile: Dockerfile restart: unless-stopped environment: WHATSAPP_TOKEN: ${WHATSAPP_TOKEN} WHATSAPP_DATA_DIR: /data PORT: 3001 # Mesmo fuso do Rails: log de envio com hora diferente da do sistema # torna impossível cruzar os dois na hora de investigar uma falha. TZ: ${TZ:-America/Sao_Paulo} volumes: # A sessão pareada vive aqui. Sem este volume, cada deploy exige escanear # o QR de novo. - "whatsapp_auth:/data" expose: - "3001" volumes: bundle_cache: whatsapp_auth: