NotariumDocumentação
Versão da documentação: latest
PT

Produção

Esta página trata de levar uma instância para produção: como colocá-la atrás de um proxy reverso da maneira certa, o que significa o invariante de instância única e como fazer backup dela. O Notarium é implantado como um único contêiner — a configuração de produção se resume às três coisas abaixo.

Proxy reverso e cabeçalhos encaminhados

Você coloca um proxy reverso (nginx, Caddy, Traefik) na frente da aplicação — ele termina o TLS e encaminha para a porta do Notarium. O requisito essencial: o proxy precisa encaminhar os cabeçalhos que descrevem o endereço externo.

O erro de deploy mais comum

O proxy reverso deve enviar X-Forwarded-Host (ou deixar o Host intacto) e X-Forwarded-Proto: https. Caso contrário, as mutações autenticadas por cookie feitas pela interface são rejeitadas como cross-origin — o sintoma é "consigo ver, mas não consigo salvar". Encaminhar X-Forwarded-Proto também é necessário para que o cookie de sessão receba a flag Secure.

O motivo: a verificação de Origin nas mutações compara a origem da requisição com o endereço que o navegador enxerga — e esse endereço chega em um cabeçalho encaminhado. As chamadas de agentes via Bearer PAT ficam isentas da verificação (elas não carregam cookie — portanto não há superfície de CSRF). O proxy, por sua vez, precisa sobrescrever os cabeçalhos encaminhados com os próprios valores, em vez de repassar direto os que vieram do cliente.

Se você ativar a autorização OAuth para agentes, defina PUBLIC_BASE_URL ao rodar atrás do proxy (por exemplo, https://notes.example.com) — um endereço externo estável para os metadados OAuth. Sem ele, o endereço é derivado dos cabeçalhos encaminhados. Veja Configuração.

Confiança no IP do cliente

Um eixo separado do endereço é o IP real do cliente. Dois limites são contados com base nele: as tentativas de login e a admissão de novos clientes OAuth. Atrás de um proxy, todas as requisições chegam do mesmo endereço; logo, sem configuração explícita, esses limites seriam contados por proxy — ou seja, para todo mundo de uma vez.

O controle para isso é o TRUST_PROXY: uma lista, separada por vírgulas, de IPs/CIDRs dos proxies imediatos.

# .env — coloque o endereço do seu próprio contêiner de proxy ou host
TRUST_PROXY=172.18.0.0/16

O padrão seguro é deixar a variável sem definir: nesse caso, o X-Forwarded-For não influencia os limites em nada, e nenhum cabeçalho consegue forjar o IP de outra pessoa. Defina-a apenas quando souber com certeza o endereço do seu proxy, e mantenha a lista enxuta.

Não coloque "todo mundo" aqui

Valores booleanos, contagens de saltos, faixas nomeadas e faixas que cobrem todos os endereços (/0) são rejeitados na inicialização. Confiar em todos os endereços significaria que qualquer cliente poderia atribuir a si mesmo um IP por cabeçalho e passar por cima do limite de login.

Essa configuração não interfere no encaminhamento de X-Forwarded-Host e X-Forwarded-Proto — são eixos independentes, e o contrato da seção anterior continua valendo inalterado.

O invariante de instância única

O Notarium foi feito para um único processo. Dois estados de autenticação vivem na memória do processo:

  • rate-limit de login — os contadores de tentativas;
  • o registro de sockets SSE — o mecanismo pelo qual a revogação de acesso derruba instantaneamente as conexões ativas.

Atrás de um balanceador de carga com várias instâncias e sem armazenamento compartilhado, esses mecanismos deixam de funcionar: um atacante multiplica o limite entre as instâncias, e revogar o acesso em uma instância não fecha uma conexão SSE mantida aberta em outra.

Várias instâncias atrás de um balanceador de carga

Ambos os estados vivem na memória do processo, então, atrás de um balanceador de carga com várias instâncias e sem armazenamento compartilhado, esses mecanismos não funcionam. Mover o banco de metadados para o Postgres dá a você um estado compartilhado, mas isso sozinho não basta para o escalonamento horizontal. Mantenha uma única instância.

Backups

O backup canônico é um comando embutido na imagem, e não uma cópia dos arquivos feita de fora: o notarium backup monta um ZIP verificado e o entrega por stream enquanto o serviço segue no ar.

docker compose exec -T notarium backup > notarium-$(date -u +%Y%m%dT%H%M%SZ).zip
docker compose exec -T notarium backup verify < notarium-20260731.zip

A verificação faz parte da rotina agendada, não é um gesto pontual: ela não altera nada e detecta corrupção de dados antes do dia em que você precisar do arquivo de backup. Para a rotina em si, um simples redirecionamento não basta — pegue a sequência de publicação segura (arquivo temporário → flush para o disco → hard link atômico) no runbook: Backup e restauração. Essa página cobre também a restauração em um volume limpo e onde o comando deixa de se aplicar.

Não copie um meta.db em uso

cp /data/meta.db, ou copiar o volume com o serviço rodando, não é backup: o banco de metadados opera em modo WAL, linhas já commitadas ainda podem estar em meta.db-wal, e arquivos copiados um a um não formam um instantâneo de um único ponto no tempo.

O que entra no backup, e por quê:

O quêPapel
/data/spacesSeus arquivos Markdown — a fonte da verdade.
/data/meta.dbO banco de metadados (histórico, usuários, acesso) — irrecuperável a partir dos arquivos.
/data/jobsArtefatos e uploads das tarefas de importação/exportação.
/data/engineOs índices derivados do motor. Ficam fora do arquivo de backup: são reconstruídos a partir dos arquivos.

Se o banco de metadados tiver sido movido para o Postgres, ou se as notas ficarem fora da raiz de dados, o comando embutido termina com erro em vez de gerar um arquivo de backup pela metade — faça backup do banco e dos diretórios montados com as ferramentas padrão do seu provedor. Para saber exatamente o que o banco de metadados guarda, veja a página Banco de dados.