version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    # PORTA DO HOST parametrizada — a do container é sempre 3000.
    #
    # POR QUE NÃO É FIXA: o mesmo NAS roda mais de um stack, e dois containers
    # não publicam a mesma porta ("driver failed programming external
    # connectivity ... port is already allocated"). O ambiente de TESTE usa a
    # 3001; a 3000 já está ocupada. Por isso o PADRÃO aqui é 3001 e não 3000:
    # é o valor que mantém ESTE ambiente de pé se o .env se perder — foi
    # exatamente o que aconteceu, e o padrão 3000 fez o container morrer com
    # "port is already allocated". Na produção (branch main) o padrão é 3000.
    #
    # Isto vivia como alteração LOCAL no docker-compose.yml do servidor — e em
    # 27/08/2026 um `git reset --hard` levou junto, derrubando o ambiente com o
    # proxy apontando para uma porta sem ninguém escutando. Parametrizado aqui,
    # a porta passa a morar no .env (que o reset não toca) e o arquivo fica
    # igual em todos os ambientes.
    #
    # ⚠️ Ao mudar, ajuste JUNTO o proxy reverso (DSM/Cloudflare) — senão o 502
    #    só muda de lugar.
    ports:
      - "${PORTA_APP:-3001}: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}

      # Endereço público e nome do sistema. Ficam aqui com PADRÃO porque não são
      # segredo — assim um .env perdido não leva junto a configuração do
      # ambiente. O .env continua mandando: se a variável existir lá, ela vence.
      #
      # ⚠️ APP_HOST é SÓ O HOST, sem "https://". O código monta os links como
      #    "https://#{APP_HOST}/motorista" (consolidacao_mailer.rb,
      #    notificacao_service.rb, gatilhos.rb) — com o esquema no valor sai
      #    "https://https://..." e todo link de e-mail e WhatsApp quebra.
      APP_HOST: ${APP_HOST:-teste.reemtransportes.com.br}
      APP_NAME: "${APP_NAME:-Reem Logística}"
      # Hosts extras aceitos além do APP_HOST (vírgula separa vários). Com
      # RAILS_ENV=production o Rails só aceita os hosts listados; o acesso pela
      # rede interna chega com o IP do NAS e era recusado com
      # "Blocked hosts: 100.75.222.23:3001". Ver config/environments/production.rb.
      HOSTS_PERMITIDOS: ${HOSTS_PERMITIDOS:-100.75.222.23}
      # A ponte do WhatsApp é alcançada pelo nome do serviço na rede do compose.
      WHATSAPP_URL: ${WHATSAPP_URL:-http://whatsapp:3001}
    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:
