Testado em 13/10/2026. Rodei este guia com o compose.yaml oficial num PC com Windows e Docker Desktop 29.6.2 (WSL2), usando um subdomínio real (lab.selfhostbr.com) e certificado Let’s Encrypt válido emitido pelo Traefik 3.7.14. A imagem n8nio/n8n baixada era a 2.43.4. Diferenças em relação a uma VPS: o PC não recebe conexões de fora, então usei o desafio DNS-01 da Cloudflare em vez do TLS challenge e publiquei as portas só em 127.0.0.1. Também apliquei limites de 1 GB/1 CPU e 2 GB/2 CPUs ao contêiner do n8n. Resultados do teste.
Este guia resume, em português, o procedimento oficial do n8n para Docker Compose (documentação, consultada em 13/10/2026). Ele sobe dois contêineres: o n8n e o Traefik, que cuida do certificado HTTPS (Let’s Encrypt) e do roteamento.
Aviso do próprio n8n: self-host exige saber configurar servidores e contêineres, gerenciar recursos e proteger a aplicação. O n8n recomenda self-host para usuários experientes e diz que erros podem causar perda de dados, falhas de segurança e indisponibilidade.
Antes de começar
- Uma VPS Linux com acesso root ou sudo. Não sabe o tamanho? Use a calculadora.
- Um domínio em que você consiga criar um registro DNS.
- Portas 80 e 443 liberadas no firewall da VPS.
1. Instale Docker e Docker Compose
Siga as instruções oficiais do Docker para a sua distribuição. Depois confira:
docker --version
docker compose version
Opcional: para rodar Docker sem sudo, adicione seu usuário ao grupo docker (sudo usermod -aG docker ${USER}) e abra uma nova sessão.
2. Aponte um subdomínio para a VPS
Crie um registro A com nome n8n (ou o que preferir) apontando para o IP da VPS. O n8n vai responder em https://n8n.seudominio.com.
3. Crie a pasta do projeto e o .env
mkdir n8n-compose && cd n8n-compose
mkdir local-files
Crie o arquivo .env:
DOMAIN_NAME=seudominio.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=America/Sao_Paulo
SSL_EMAIL=voce@seudominio.com
O GENERIC_TIMEZONE define o fuso usado por Cron e outros nós de agendamento. Se você não definir, o padrão é Nova York (segundo a documentação).
4. Crie o compose.yaml
Use o arquivo da documentação oficial, copiado daqui. Os pontos principais:
- O serviço
traefikescuta nas portas 80 e 443, redireciona HTTP para HTTPS e obtém o certificado via TLS challenge, usando oSSL_EMAIL. - O serviço
n8nusa a imagemn8nio/n8n(taglatest; veja a nota sobrestableabaixo) e expõe a porta 5678 apenas em 127.0.0.1, ou seja, o acesso externo passa pelo Traefik. - Volumes:
n8n_data(em/home/node/.n8n), onde ficam o banco SQLite e a chave de criptografia;traefik_datacom os certificados; e a pasta./local-filesmontada em/files. - A variável
N8N_WEBHOOK_URLexiste a partir do n8n 2.30.0; em versões anteriores, useWEBHOOK_URL.
Observação de segurança: o exemplo oficial inclui --api.insecure=true no Traefik, que habilita o painel/API do Traefik sem autenticação. Como o arquivo não publica a porta 8080, esse painel não fica exposto para fora. Ainda assim, se não for usar o painel, você pode remover essa linha. Isto é uma recomendação nossa, não da documentação.
Achado do teste: latest não é stable. Em 13/10/2026 a tag latest baixou a versão 2.43.4, que a própria documentação listava como beta (a stable era a 2.42.7). Em produção, considere fixar a imagem como n8nio/n8n:stable ou numa versão específica, como n8nio/n8n:2.42.7.
5. Suba os contêineres
sudo docker compose up -d
Para parar: sudo docker compose stop. Acesse https://n8n.seudominio.com e crie a conta de administrador. A documentação avisa que o acesso é só por HTTPS.
6. Depois de subir
- Backup: faça cópia regular do volume
n8n_data. Sem a chave de criptografia que fica nele, as credenciais salvas não podem ser lidas. - Atualizações: o n8n lança uma versão minor quase toda semana. Use a versão
stableem produção, já que abetapode ser instável (documentação). Acompanhe os alertas de segurança. - Banco de dados: o padrão é SQLite. Para uso maior ou queue mode, a documentação recomenda PostgreSQL (docs).
Opcional: limitar memória e CPU
Para o n8n não consumir a VPS inteira, você pode adicionar ao serviço n8n:
deploy:
resources:
limits:
memory: 1g
cpus: "1"
Opcional: certificado via DNS (Cloudflare)
Se o servidor não pode receber conexões na porta 443 durante a emissão (foi o caso no meu teste), troque as duas linhas do mytlschallenge por:
- "--certificatesresolvers.mytlschallenge.acme.dnschallenge=true"
- "--certificatesresolvers.mytlschallenge.acme.dnschallenge.provider=cloudflare"
Passe também CF_DNS_API_TOKEN no environment: do Traefik, usando um token da Cloudflare com permissão apenas de DNS Edit na sua zona. O Traefik cria e apaga sozinho o registro TXT _acme-challenge. No meu teste não sobrou nenhum registro na zona depois.
Resultados do teste
Workflow de teste: Webhook → Edit Fields → Respond to Webhook, chamado por HTTPS através do Traefik. Os números de memória vêm do docker stats.
| Limite do contêiner | Até responder HTTPS (1ª subida, com emissão do certificado) | Memória ociosa | 200 chamadas sequenciais | 200 chamadas, 4 em paralelo | Memória durante a carga | OOM/reinícios |
|---|---|---|---|---|---|---|
| 1 GB / 1 CPU | 21,6 s | 435 MiB | 200/200 OK em 11,5 s | 200/200 OK | ~425 MiB (CPU ~95%) | nenhum |
| 2 GB / 2 CPUs | 21,3 s | 556 MiB | 200/200 OK em 10,2 s | 200/200 OK | ~500 MiB (CPU ~164%) | nenhum |
O Traefik usou entre 21 e 31 MiB. As imagens ocupam 1,79 GB (n8n) e 253 MB (Traefik) em disco. Limites do teste: o workflow é mínimo e o tempo inclui a latência local, então workflows com IA, arquivos ou o nó Code vão consumir mais. Na primeira subida, cerca de 20 s foram de criação do banco e emissão do certificado; um reinício levou de 5 a 10 s.
Onde rodar
Veja planos com preço em reais em Quanto custa hospedar n8n no Brasil. Exemplo: Hostinger KVM 2 (2 vCPU, 8 GB) ver plano ↗.