O que é Docker: conhecimento mínimo necessário para iniciantes em n8n
O ponto onde a instalação do n8n mais trava não é o próprio n8n, mas o Docker que está à frente dele. Seguindo o tutorial, você copia os cinco comandos, o container sobe, e com dois cliques na interface já dá para usar; no dia seguinte você volta e descobre que todos os workflows sumiram — a razão é apenas que faltava uma coisa naqueles cinco comandos -v。
Este artigo cobre apenas a parte do Docker necessária para instalar o n8n: image, container, volume, port. Quatro palavras. Quanto a network mode, Compose, construir a própria image, deixe para quando você realmente precisar; aprender antes também se esquece.
O pré-requisito é apenas um: saber digitar comandos no terminal e saber o que é "port". Nunca ter tocado em Docker não afeta em nada.
- Por que o n8n acaba sempre instalado no Docker
- Quatro palavras: image, container, volume, port
- Primeiro instale o Docker
- Subir um n8n, três passos
- Como saber se está instalado
- Em qual arquivo os dados realmente ficam
- Seis erros que você realmente vai encontrar
- Alguns pontos de segurança relacionados ao n8n
Por que o n8n acaba sempre instalado no Docker
A página oficial de instalação oferece vários caminhos: instalação global via npm, execução direta com npx, Docker, versão desktop. Os dois primeiros são os mais leves, um npm install -g n8n e pronto; o problema é que eles amarram o n8n ao Node da sua máquina. O n8n é exigente com a versão do Node, a documentação indica o intervalo de 20.19 a 24.x. Um dia, se você atualizar o Node para 26 por causa de outro projeto, o n8n para de funcionar junto, e o erro não necessariamente será claro.
O Docker muda a abordagem: empacota o n8n junto com o Node, as bibliotecas de sistema e os dados de fuso horário de que ele precisa em um único pacote, e esse pacote roda igual em qualquer máquina. Eu entrei de propósito na image 2.43.7 para dar uma olhada: o Node é 26.7.0, e a image base é Alpine. Nada disso tem qualquer relação com você ter Node 18 ou 26 instalado no host.
O custo também precisa ser dito com clareza. Você ganha uma camada extra para manter: a image ocupa disco (2.43.7 descompactada fica em 1.8 GB), se der problema você precisa olhar mais um lugar nos logs, e a atualização deixa de ser "npm update" para virar "trocar a image e rodar de novo". Eu acho que vale a pena — na hora de atualizar, muda a tag, remove o container, roda de novo, três minutos, sem se preocupar com a versão do Node.
Se for só para brincar localmente por dois dias, eu não recomendo usar Docker, npm é mais rápido. Se pretende rodar a longo prazo, ou disponibilizar para colegas, vá direto de Docker, não faça desvios.
Quatro palavras: image, container, volume, port
Image
A image é um pacote somente leitura já montado por outra pessoa, dentro dele há um sistema de arquivos completo capaz de rodar o n8n.n8nio/n8n é o nome,2.43.7 é a tag. Sob o mesmo nome ficam penduradas várias tags, uma tag corresponde a uma versão.
A tag escrita como latestsignifica "última versão estável". Em produção eu não recomendo escrever assim: um dia o container reinicia e puxa a nova image sem querer, o comportamento muda, e você nem sabe de onde começar a investigar. Fixe o número da versão, trate a atualização como uma tarefa separada.

docker pull é exatamente oContainer
A image é estática.docker run O processo que roda depois é que se chama container. O container é igual à image mais uma camada gravável, qualquer coisa que você altere dentro é escrita nessa camada. Se o container for removido, essa camada desaparece junto — essa frase é a origem de todas as armadilhas a seguir.
卷
Por isso os dados do n8n não podem ficar dentro do container. O volume é um diretório no host, gerenciado pelo Docker, montado em algum caminho dentro do container. O caminho que o n8n reconhece é /home/node/.n8n, o banco de dados, as chaves de criptografia e os logs de eventos estão todos lá.
Contei: um recém-criado com a conta owner, que já executou um workflow .n8n diretório, 5.5 MB. Desses database.sqlite 1.5 MB, além de um arquivo de 4 MB -wal arquivo. Só isso, se perder é começar tudo de novo.
port
-p 5678:5678, o lado esquerdo dos dois-pontos é a port do host, o lado direito é a port dentro do container. O n8n dentro do container sempre escuta na 5678 (a menos que você altere N8N_PORT), se quiser trocar o número externamente, mexa só no lado esquerdo:-p 8080:5678。
escrito como 127.0.0.1:5678:5678 fica vinculado apenas à máquina local, não dá para conectar de fora. Nos meus testes eu sempre uso essa forma, para não esquecer de fechar.
Primeiro instale o Docker
No Ubuntu / Debian o mais prático é aquele script oficial:
curl -fsSL https://get.docker.com | sh
Ele adiciona o repositório oficial, instala o docker-ce, com o plugin compose. Quem se incomoda com "jogar direto no sh o que sai do curl", vá pelo caminho do repositório oficial via apt, os passos estão na documentação do Docker, só que é mais longo.
Depois de instalar, execute dois comandos para ver a versão:
docker --version
# Docker version 29.1.3, build 29.1.3-0ubuntu3~24.04.2
Esta minha 232 é Ubuntu 24.04 + Docker 29.1.3. Você pode usar 24 ou 25, os comandos não têm diferença.
Docker por padrão exige root ou sudo. Alguns dizem que adicionar o usuário ao docker grupo elimina a necessidade de sudo, o que é verdade, mas equivale a dar àquele usuário permissões de root, a razão está na seção de segurança.
Subir um n8n, três passos
Primeiro passo: criar o volume
docker volume create n8n_data
# n8n_data
Se o nome do volume for exibido, está criado. Não criar também funciona,docker run escrever em -v n8n_data:/home/node/.n8n será criado automaticamente — mas crie uma vez primeiro, assim você confirma que ele realmente existe.
Segundo passo: colocar para rodar
docker run -d
--name n8n
-p 127.0.0.1:5678:5678
-e TZ=Asia/Shanghai
-e GENERIC_TIMEZONE=Asia/Shanghai
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
-v n8n_data:/home/node/.n8n
n8nio/n8n:2.43.7
Comparado ao comando original da documentação oficial, alterei dois pontos.
Um ponto foi adicionar -d. A documentação fornece docker run -it --rm, executa em primeiro plano, ao fechar o terminal ou Ctrl+C, o n8n para;--rm e ainda remove o container de quebra. Usar assim durante depuração é bem limpo, mas para execução contínua não funciona, adicione -d para deixá-lo em segundo plano.
O outro ponto foi adicionar antes da porta 127.0.0.1:。A documentação diz -p 5678:5678, isso equivale a vincular em 0.0.0.0; se a máquina tiver IP público, qualquer um que escaneie a 5678 verá sua página de login. Na minha máquina 232, a 5678 está ocupada, então na prática uso -p 127.0.0.1:5681:5678, o mapeamento é o mesmo.
As duas variáveis de fuso horário precisam ser definidas.TZ controla o horário do sistema do container,GENERIC_TIMEZONE controla como o próprio n8n calcula o tempo; o Schedule Trigger usa a segunda. Definir apenas TZ, as tarefas agendadas continuam em UTC, o que você pensa ser 9 da manhã vira 17h no horário de Pequim. Esse tipo de coisa não deixa nenhuma exceção no log.
Terceiro passo: ver os logs, esperar ele subir
docker logs -f n8n
Na primeira inicialização ele executa dezenas de migrações de banco de dados,Starting migration ... 和 Finished migration ... alternando, é normal. Quando estas duas linhas aparecerem:
Version: 2.43.7
Editor is now accessible via:
http://localhost:5678
Aquele http://localhost:5678 é um endereço interno do container, não abre no navegador. O que você consegue abrir é http://服务器IP:5678, ou na própria máquina http://127.0.0.1:5678. Essa linha já enganou muita gente, inclusive eu na primeira vez que rodei.
O 2.43.7 na inicialização ainda emite cinco avisos de deprecation, falando sobre N8N_RUNNERS_MODE、N8N_UNVERIFIED_PACKAGES_ENABLED Estes valores padrão terão de ser alterados mais tarde. Não afeta o uso, é para preparar o caminho para versões futuras. Além disso, há ainda uma linha Failed to start Python task runner in internal mode. because Python 3 is missing from this system.—— a image não tem Python instalado, se usares apenas o nó Code em JS não precisas de te preocupar com isso.

Depois de criar a conta, entra-se. Este passo não tem sentido se não for escrito no volume — a verificação abaixo explicará como confirmar que ficou realmente gravado em disco.
Como saber se está bem instalado
Quatro verificações, todas feitas no terminal.
docker psEm STATUS estáUp, PORTS tem mapeamento, IMAGE é a tag que especificaste.curl -s http://127.0.0.1:5678/healthzDevolve{"status":"ok"}. Este endpoint apenas indica que o processo está vivo.docker exec n8n n8n --version回2.43.7, corresponde à tag que deste.docker restart n8n, espera dez ou mais segundos e abre a página novamente, já não te deve pedir para criar conta.
O ponto 4 é o mais fácil de ignorar e o mais valioso. Verifica duas coisas ao mesmo tempo: o volume está montado corretamente e os dados estão realmente fora do container.

Quando tirei esta captura de ecrã, aproveitei para ver dentro do container .n8n, 5.5 MB, corresponde ao que foi dito acima. Se o seu du -sh aparecer como algumas centenas de K, provavelmente os dados foram gravados na camada gravável do container e o volume não foi montado.
Em qual arquivo os dados realmente estão
Depois que o volume é criado, a localização real no host é determinada pelo Docker; use este comando para verificar:
docker volume inspect n8n_data
# [
# {
# "CreatedAt": "2026-11-02T09:28:41+08:00",
# "Driver": "local",
# "Mountpoint": "/var/lib/docker/volumes/n8n_data/_data",
# "Name": "n8n_data",
# "Scope": "local"
# }
# ]
"Mountpoint" é a localização real dele no host. Nesta minha máquina, movi o diretório raiz de dados do Docker para /data/docker, por isso o que aparece é /data/docker/volumes/n8n_data/_data; em uma máquina com instalação padrão, é o /var/lib/docker/...acima. Considere a saída da sua própria máquina.
Dentro do container, é assim como o n8n enxerga:
docker exec n8n ls -la /home/node/.n8n
# -rw-r--r-- 1 node node 1519616 Nov 2 09:29 database.sqlite
# -rw-r--r-- 1 node node 32768 Nov 2 09:38 database.sqlite-shm
# -rw-r--r-- 1 node node 4136512 Nov 2 09:37 database.sqlite-wal
# -rw-r--r-- 1 node node 7972 Nov 2 09:37 n8nEventLog-1.log
# -rw-r--r-- 1 node node 526 Nov 2 09:38 n8nEventLog.log
workflows, registros de execução e credenciais criptografadas estão todos em database.sqlite . A chave de criptografia usada para descriptografar as credenciais está no mesmo diretório, por padrão é o arquivo config , gerado automaticamente na primeira inicialização.
Portanto, fazer backup do n8n significa duas coisas: este diretório e o número da versão. Se você fizer backup apenas do sqlite sem a chave, ao restaurar em outra máquina, as credenciais ficarão todas ilegíveis.
Se quiser trocar para um diretório de host especificado por você (por exemplo /data/n8n), altere o -v n8n_data:/home/node/.n8n Troque por -v /data/n8n:/home/node/.n8n e pronto. Isso é o «bind mount»: o diretório fica sob a sua gestão, o backup é mais intuitivo, o custo é que você mesmo tem de resolver as permissões — o próximo obstáculo é exatamente esse.
Seis erros que você realmente vai encontrar
1. Esqueceu o -v, apagar o container equivale a apagar o banco de dados
Fiz um teste comparativo com dois containers, na mesma máquina, com a mesma image: o que tinha -v n8n_data:/home/node/.n8n , após reiniciar, a interface retornou «se exibir a configuração inicial» como false; o outro, sem -v , a mesma interface retornou true— ele voltou a ser uma instância vazia.
Todo o processo não dá erro, não dá alerta. Você só descobre um dia quando abre e vê que o workflow sumiu.
Como verificar:docker inspect n8n, role para cima e procure "Mounts" aquele trecho, se aparecer "Destination": "/home/node/.n8n" significa que está montado; se o trecho inteiro estiver vazio, então é perigoso.
2. Montar um diretório do host, retorna EACCES
Queria usar bind mount, o diretório já foi criado e é só montar, então:
Error: Failed to load command "start"
Error: EACCES: permission denied, open '/home/node/.n8n/config'
Antes ainda estava registrando normalmente o log de migração, de repente travou aqui. Porque o n8n na image não é root, é um usuário uid 1000 node(docker exec n8n id É possível ver uid=1000(node)), e o seu mkdir diretório criado tem proprietário root, 755, outros não podem escrever.
Basta alterar o proprietário:
chown -R 1000:1000 /data/n8n
Depois de alterar, execute novamente, mesmo diretório, mesmo comando, 200, subiu normalmente, e os arquivos realmente foram gravados no diretório do host. No host, quem é o uid 1000 não importa, dentro do container o que vale é 1000.
3. Porta ocupada
docker: Error response from daemon: failed to set up container networking:
driver failed programming external connectivity on endpoint n8n
(...): failed to bind host port 0.0.0.0:5678/tcp: address already in use
Significa que a 5678 no host já está em uso por alguém, não tem nada a ver com o interior do container. Primeiro veja quem é:
ss -ltnp 'sport = :5678'
A situação comum é que o seu container n8n anterior ainda está rodando,docker ps É possível ver. Ou o container antigo foi removido mas não foi completamente, o mais simples é trocar de porta e subir primeiro.
4. Acessar com IP + http, após o login volta para a página de login
A página abre, usuário e senha estão corretos, clicar em login não dá erro, e então a página volta para a caixa de login. Parece que a senha está errada, mas na verdade é um problema de cookie.
O cookie de login do n8n tem Secure marca (N8N_SECURE_COOKIE Por padrão, é true), e o navegador só permite que ele seja salvo em HTTPS. Se você acessar via http, o servidor continua retornando 200, mas o navegador simplesmente descarta esse cookie, então a próxima requisição fica sem estado de login.
Dois caminhos: a abordagem correta é colocar um Nginx na frente com certificado; para depuração temporária em rede interna, adicione -e N8N_SECURE_COOKIE=false, e lembre-se de remover essa linha depois de ajustar. Não a trate como configuração de longo prazo — isso equivale a deixar seu usuário e senha trafegarem em canal de texto claro.
5. Fechar o terminal e o n8n para junto
Se você seguiu o comando docker run -it --rm da documentação, Ctrl+C encerra. Ele não é um serviço em background, é um processo em primeiro plano no seu terminal.
补 -d Execute novamente; se já estiver rodando,docker start n8n também consegue trazê-lo de volta, mas aquele container já foi removido com --rm , só resta recriar docker run— os dados estão no volume, ainda estão lá.
6. Usou latest e um dia o comportamento mudou
Sem erro, sem alerta, apenas um dia após reiniciar os valores padrão dos nós, a interface, ou até o nome de algum parâmetro mudou. A razão é que você puxou uma nova versão.
Fixe o número da versão e trate a atualização como uma tarefa séria: primeiro faça backup do volume, depois troque a tag, e após subir execute dois workflows críticos para verificar os resultados. A atualização em si não tem nada de técnico demais, o problema está todo em "não saber o que mudou".
Alguns itens de segurança relacionados ao n8n
Não exponha a porta 5678 diretamente à internet pública.O n8n tem página de login, mas é uma aplicação auto-hospedada, sem proteção adicional além do login, e os scanners procuram esse tipo de porta todos os dias. Colocá-lo em 0.0.0.0 sem reverse proxy e sem HTTPS é como pendurar a chave de casa na porta. A configuração que usei nos testes -p 127.0.0.1:5678:5678 já bloqueia o acesso externo.
docker grupo equivale a root.Quem consegue / montar algo no container pode alterar qualquer arquivo no host. Pense nisso antes de dar permissões a colegas.
Trate os volumes como segredos.Ali dentro database.sqlite ficam os textos cifrados de todas as credenciais, e no mesmo diretório está a chave de descriptografia. Quem copiar os dois juntos terá os tokens de todas as suas contas de terceiros em texto claro. Onde colocar o backup importa mais do que o backup em si.
Não escreva senhas na linha de comando.docker run -e DB_PASSWORD=xxx Elas ficam no docker inspect output, e qualquer pessoa que execute o comando consegue vê-las. Para passar valores sensíveis, use um arquivo env ou as variáveis com sufixo _FILE .
Resumo
Quatro palavras bastam para começar: image é o pacote, container é o pacote em execução, volume é o terreno fora do pacote, port é o número da porta.
O único lugar onde instalar o n8n realmente dá problema é um só: o volume não foi montado. Ele não dá erro, e você também não percebe na hora; quando percebe, o workflow já se foi. Então a primeira coisa após instalar é docker restart uma vez, para ver se os dados ainda estão lá.
O resto é questão de prática. Com o uso, você vai perceber que a maior vantagem do Docker não é "multiplataforma", é "se der problema, pode apagar tudo e recomeçar" — os dados estão no volume, o container pode ser descartado a qualquer momento.
O post anterior écomo investigar erros de inicialização do n8n e ocupação de portas, lá fala sobre a situação de não conseguir iniciar. O índice da série completa estáaqui, os de troubleshooting eu organizei separadamente napágina de troubleshooting.
Referências
- Install with Docker: oficial
docker runcomandos、docker volume create、/home/node/.n8nexplicação do volume, e os passos para atualizar a imagem - Instalar usando Docker Compose: a configuração da versão compose,
5678:5678aquele comentário dizendo "a única porta que deve ser exposta externamente" - Variáveis de ambiente de Deployment:
N8N_PORTpadrão 5678,N8N_LISTEN_ADDRESSpadrão::、N8N_USER_FOLDER与N8N_ENCRYPTION_KEY - Variáveis de ambiente de Security:
N8N_SECURE_COOKIEpadrãotrue、N8N_ENFORCE_SETTINGS_FILE_PERMISSIONSpadrãofalse - volumes do Docker: o volume existe no host
/var/lib/docker/volumes/<名字>/_data, e a diferença entre ele e o bind mount - lista de tags de n8nio/n8n: um tag por versão, é possível consultar o digest da image e o tamanho comprimido
- Instalar Docker Engine no UbuntuPassos completos usando o repositório oficial do apt; se não quiser usar o script tudo-em-um, siga este caminho.
Última atualização: 2 de novembro de 2026, usando n8n 2.43.7.

