Deploy: variáveis de ambiente configuráveis + docs dos dois modos do Coolify
TZ (com tzdata), GUNICORN_TIMEOUT e GUNICORN_LOG_LEVEL agora têm default no Dockerfile e podem ser sobrescritos via Coolify → Environment Variables ou .env (modelo em .env.example). TZ corrige o carimbo "exportada em" (sessao.marcar_exportada), que sem isso saía em UTC. Workers continua literal em -w 1, de propósito — não é variável. Cabeçalhos do Dockerfile e docker-compose.yml reescritos para descrever os dois modos de deploy no Coolify (Application/Dockerfile, em produção desde 04/09, e Docker Compose) e o caminho de volume que de fato funciona: Directory mount em /data/coolify/applications/<uuid>/clientes, dados enviados por scp da pasta ses-mg/. .gitattributes fixa LF também em Dockerfile, docker-compose.yml e .env.example — o autocrlf do Windows já tinha reescrito o Dockerfile para CRLF uma vez nesta máquina. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+45
-21
@@ -1,47 +1,71 @@
|
||||
# Deploy em VPS pelo painel Coolify (recurso do tipo "Docker Compose").
|
||||
# Deploy da Exportação da SD — a imagem é a do Dockerfile; este arquivo é UM dos
|
||||
# dois jeitos de subi-la no Coolify, e serve também para rodar local.
|
||||
#
|
||||
# ANTES do primeiro deploy, ponha os dados do cliente em um caminho FIXO do
|
||||
# host, FORA da pasta que o Coolify clona — ele re-clona a cada deploy, e
|
||||
# clientes/ está no .gitignore, então o clone nunca traz esses dados:
|
||||
# ── MODO 1 · Application (Dockerfile) — o que está em produção (2026-09-04) ──
|
||||
#
|
||||
# scp -r clientes/ usuario@vps:/dados/exporta-sd/clientes
|
||||
# Neste modo o Coolify IGNORA este arquivo por completo: builda o Dockerfile e
|
||||
# configura tudo pela interface. O que o volume e as variáveis daqui dizem tem
|
||||
# de ser reproduzido lá:
|
||||
#
|
||||
# Não precisa de chown manual: o entrypoint.sh da imagem roda como root no
|
||||
# início do container e ajusta o dono do volume para o usuário `sd` antes de
|
||||
# derrubar privilégio e subir o gunicorn — ver entrypoint.sh e o ENTRYPOINT
|
||||
# no Dockerfile. (Uma reconsequência: cada `scp` novo devolve os arquivos ao
|
||||
# usuário do ssh no host; some sozinho no próximo restart do container.)
|
||||
# Depois, no Coolify → Environment Variables, aponte o volume para lá:
|
||||
# Persistent storage → Add mount → "Directory mount"
|
||||
# Source Path: /data/coolify/applications/<uuid-da-app>/clientes
|
||||
# (o próprio Coolify sugere esse caminho; ele sobrevive
|
||||
# a redeploy — é a pasta de storage da app, não o clone)
|
||||
# Destination Path: /app/clientes
|
||||
# Mesmo esquema para _derivados, só se for usar a linha de comando.
|
||||
#
|
||||
# CLIENTES_DIR=/dados/exporta-sd/clientes
|
||||
# DERIVADOS_DIR=/dados/exporta-sd/_derivados # só se usar a linha de comando
|
||||
# Dados: a pasta do host nasce VAZIA. Copie o conteúdo para dentro dela —
|
||||
# aponte para "ses-mg", não para "clientes", ou o nível duplica
|
||||
# (.../clientes/clientes/ses-mg):
|
||||
#
|
||||
# Sem essas variáveis, o padrão ./clientes cai dentro da pasta do clone, o
|
||||
# compose cria o diretório VAZIO sem avisar e o primeiro upload morre com
|
||||
# "Arquivo canônico ausente".
|
||||
# scp -r "D:/Exporta-SD/clientes/ses-mg" usuario@vps:/data/coolify/applications/<uuid>/clientes/
|
||||
#
|
||||
# Resto do painel: porta exposta 5000, réplicas 1 (ver o comentário de -w 1 no
|
||||
# Dockerfile), e o domínio o Coolify publica via Traefik.
|
||||
# e confira no host: ls /data/coolify/applications/<uuid>/clientes/ses-mg/contrato/
|
||||
# Tem de listar itens.yaml E linhas-os.yaml — sem o segundo, o fallback da
|
||||
# linha de OS desliga e `linha_os` vira pendência só no VPS.
|
||||
#
|
||||
# Variáveis: aba Environment Variables (nomes e defaults em .env.example).
|
||||
# Réplicas: 1 (ver o comentário de -w 1 no Dockerfile).
|
||||
#
|
||||
# ── MODO 2 · Docker Compose (ou local) ──────────────────────────────────────
|
||||
#
|
||||
# O Coolify lê este arquivo. Ponha os dados num caminho fixo do host, fora da
|
||||
# pasta que ele clona, e aponte CLIENTES_DIR para lá (Environment Variables no
|
||||
# Coolify, ou um .env ao lado deste arquivo — copie .env.example). Sem a
|
||||
# variável, o padrão ./clientes cai dentro do clone, o compose cria o
|
||||
# diretório VAZIO sem avisar e o primeiro upload morre com "Arquivo canônico
|
||||
# ausente".
|
||||
#
|
||||
# Nos dois modos não há chown manual: o entrypoint.sh roda como root ao subir
|
||||
# o container, ajusta o dono do volume para o usuário `sd` e só então derruba
|
||||
# privilégio e inicia o gunicorn. Um scp novo devolve os arquivos ao usuário do
|
||||
# ssh; resolve sozinho no próximo restart.
|
||||
|
||||
services:
|
||||
exporta-sd:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: exporta-sd:local
|
||||
# Sem `ports:` de propósito: no Coolify o Traefik alcança o container pela
|
||||
# rede interna. `expose` publica a porta só para dentro dessa rede.
|
||||
# Para rodar fora do Coolify, troque por: ports: ["5000:5000"].
|
||||
expose:
|
||||
- "5000"
|
||||
# Só ESPELHA os defaults do Dockerfile — o valor de verdade mora lá (ENV e
|
||||
# ${VAR:-default} no CMD), porque no Modo 1 este bloco nem é lido. Aqui a
|
||||
# única função é deixar o operador trocar pelo .env sem editar YAML.
|
||||
environment:
|
||||
PORT: "5000"
|
||||
PORT: ${PORT:-5000}
|
||||
TZ: ${TZ:-America/Sao_Paulo}
|
||||
GUNICORN_TIMEOUT: ${GUNICORN_TIMEOUT:-120}
|
||||
GUNICORN_LOG_LEVEL: ${GUNICORN_LOG_LEVEL:-info}
|
||||
volumes:
|
||||
# OBRIGATÓRIO. O app lê clientes/ses-mg/contrato/itens.yaml a cada
|
||||
# análise (e contrato/linhas-os.yaml, se existir, como fallback da linha
|
||||
# de OS) e grava SD.md em clientes/ses-mg/projetos/. O caminho no
|
||||
# container é fixo: caminhos.py resolve clientes/ a partir da raiz do
|
||||
# código, que é o WORKDIR /app. Sem esta montagem, a tela inicial abre
|
||||
# e o primeiro upload falha com "Arquivo canônico ausente".
|
||||
# código, que é o WORKDIR /app.
|
||||
- ${CLIENTES_DIR:-./clientes}:/app/clientes
|
||||
# Saída da linha de comando (exporta_sd.py --dir _derivados/export).
|
||||
# A aplicação web entrega o JSON pelo download, não por aqui.
|
||||
|
||||
Reference in New Issue
Block a user