Automação de workflows self-hosted — do zero ao servidor em produção.
O N8N é uma ferramenta de automação de workflows com interface visual — você conecta nodes (nós) em um canvas, define gatilhos e deixa o fluxo rodar sozinho. É o equivalente open-source do Zapier ou do Make, mas que você instala e controla no seu próprio servidor.
Roda na nuvem deles. Você paga por execução. Dados passam por servidores deles. Limite de steps/mês. Sem acesso ao código interno.
Roda no seu VPS. Sem custo por execução. Dados ficam no seu servidor. Ilimitado (memória é o limite). Código aberto, extensível.
O N8N pode ser instalado de três formas. Para um VPS Ubuntu com NGINX, o Docker é o caminho recomendado — isola o processo, facilita updates e não conflita com o PHP-FPM da stack existente.
docker run -d \ --name n8n \ --restart unless-stopped \ -p 127.0.0.1:5678:5678 \ -e N8N_HOST=n8n.seudominio.com \ -e N8N_PORT=5678 \ -e N8N_PROTOCOL=https \ -e WEBHOOK_URL=https://n8n.seudominio.com/ \ -e GENERIC_TIMEZONE=America/Belem \ -v n8n_data:/home/node/.n8n \ docker.n8n.io/n8nio/n8n
127.0.0.1 expõe a porta apenas internamente. O NGINX fará o proxy reverso público. Nunca exponha a porta 5678 diretamente na internet sem autenticação.
Abre em http://localhost:5678. Dados ficam em ~/.n8n.
Resposta esperada: {"status":"ok"}
Ao abrir o N8N pela primeira vez, você cria uma conta local (admin). A interface tem três áreas principais:
| Área | O que faz |
|---|---|
| Canvas | Área de edição visual onde você conecta nodes e testa o workflow |
| Sidebar esquerda | Lista de workflows salvos, credenciais, execuções e configurações |
| Painel direito | Configuração do node selecionado, parâmetros, mapeamento de dados |
| Ação | Como fazer |
|---|---|
| Adicionar node | Clique no + à direita de qualquer node, ou clique com botão direito no canvas |
| Conectar nodes | Arraste a bolinha de saída de um node até a entrada do próximo |
| Testar um node | Clique no node → botão Execute node (triângulo) no painel |
| Testar tudo | Botão Execute workflow no topo da tela |
| Ver dados | Clique no node após executar — mostra input e output de cada item |
| Mover canvas | Clique e arraste no fundo, ou scroll para zoom |
| Ativar workflow | Toggle no canto superior direito — ativa o gatilho automático |
Um workflow é um fluxo de automação salvo. Ele começa com um trigger (gatilho) e encadeia nodes até completar a tarefa. Um workflow pode estar ativo (roda automaticamente) ou inativo (só executa manualmente).
Cada bloco no canvas é um node. Ele recebe dados, processa, e passa adiante. Há três tipos:
A unidade de dados que flui entre nodes. Um node pode produzir um item (um registro) ou vários (uma lista). O próximo node recebe todos os itens e processa cada um.
# Estrutura de um item
{
"json": {
"nome": "Daniel",
"email": "daniel@exemplo.com"
}
}
Cada vez que o workflow roda é uma execução. O N8N guarda o histórico de execuções com status (sucesso/erro), tempo e dados de cada etapa. Acesse em Executions na sidebar.
| Tipo | Como funciona | Exemplo |
|---|---|---|
| Webhook | Uma URL recebe uma chamada e dispara o workflow | GitHub envia um POST ao fazer push |
| Cron / Schedule | Executa em horário fixo (igual a um cron job) | Todo dia às 08h00 |
| Polling | Verifica a fonte a cada X minutos em busca de mudanças | Novo e-mail no Gmail a cada 5 min |
| Manual | Roda só quando você clica no botão | Útil para testes |
O N8N tem mais de 400 integrações. Conhecer os nodes fundamentais permite construir qualquer automação — o resto é só configuração específica de serviço.
Conecta o N8N a qualquer API. Configurações principais:
| Campo | O que preencher |
|---|---|
| Method | GET, POST, PUT, PATCH, DELETE |
| URL | Endpoint da API — pode usar expressões: {{ $json.url }} |
| Authentication | Escolha uma credencial salva (Bearer, Basic, API Key…) |
| Body | JSON, Form Data ou Raw — para POST/PUT |
| Query Parameters | Parâmetros de URL adicionados automaticamente |
| Response | Escolha JSON para já receber o objeto parseado |
Quando os nodes visuais não bastam, use o node Code. Dois modos:
// Recebe todos os itens de uma vez
const items = $input.all();
const result = items.map(item => ({
json: {
nome: item.json.name.toUpperCase(),
total: item.json.qty * item.json.price
}
}));
return result;
// Roda uma vez por item
// $input.item é o item atual
const nome = $input.item.json.name;
const preco = $input.item.json.price;
return {
json: {
resumo: `${nome}: R$ ${preco}`
}
};
$input, $json, $node, $workflow e $execution. Para chamadas HTTP dentro do Code, use o node HTTP Request separado — é mais limpo e mantém as credenciais fora do código.
Expressões permitem usar dados dinâmicos em qualquer campo de qualquer node. A sintaxe é {{ expressão }} e usa JavaScript dentro das chaves duplas.
# Item atual (saída do node imediatamente anterior)
{{ $json.campo }}
{{ $json.objeto.campo_aninhado }}
{{ $json.lista[0] }}
# Todos os itens do node anterior
{{ $input.all() }}
{{ $input.first().json.campo }}
{{ $input.last().json.campo }}
# Acessa a saída de um node com nome exato
{{ $('Nome do Node').item.json.campo }}
{{ $('Nome do Node').all() }}
{{ $('Nome do Node').first().json.email }}
| Variável | O que retorna |
|---|---|
$json | Dados JSON do item atual |
$now | Data/hora atual (objeto Luxon) |
$today | Data de hoje no início do dia |
$workflow.id | ID do workflow |
$workflow.name | Nome do workflow |
$execution.id | ID único desta execução |
$vars.NOME | Variável de ambiente definida nas configurações |
$parameter.campo | Parâmetro estático do próprio node |
# Formatar data
{{ $now.toFormat('dd/MM/yyyy') }}
{{ $now.minus({ days: 1 }).toISO() }}
# Concatenar texto
{{ 'Olá, ' + $json.nome + '!' }}
{{ `Pedido #${$json.id} — R$ ${$json.total.toFixed(2)}` }}
# Condicional inline
{{ $json.status === 'ativo' ? 'Ativo' : 'Inativo' }}
# Tratar valor nulo
{{ $json.email ?? 'sem-email@exemplo.com' }}
# Acessar campo com espaço no nome
{{ $json['nome completo'] }}
undefined ou causar erro, o node inteiro falha. Sempre use ?? (nullish coalescing) para valores que podem ser nulos.
Credenciais armazenam chaves de API, senhas e tokens de forma criptografada. Você configura uma vez e reutiliza em qualquer node sem expor os valores nos workflows.
| Tipo | Quando usar |
|---|---|
| HTTP Header Auth | API que usa header customizado (X-Api-Key, Authorization…) |
| HTTP Basic Auth | Autenticação usuário/senha em chamadas HTTP |
| Bearer Token | JWTs e tokens estáticos de API |
| OAuth2 | Google, GitHub, Slack e qualquer serviço OAuth — o N8N gerencia o refresh |
| SMTP | Servidor de e-mail para o node Send Email |
| Postgres / MySQL | Conexão direta a banco de dados |
-e MINHA_CHAVE=valor) e acesse com $vars.MINHA_CHAVE nas expressões. Isso evita credenciais hardcoded no banco.
Com o container rodando em 127.0.0.1:5678, configure o NGINX como proxy reverso para expor o N8N num subdomínio com HTTPS.
server {
listen 80;
server_name n8n.seudominio.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.seudominio.com;
# Gerenciado pelo Certbot:
ssl_certificate /etc/letsencrypt/live/n8n.seudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.seudominio.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Tamanho máximo do body — útil para workflows com uploads
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
# WebSockets — necessário para o editor do N8N
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Timeout maior para workflows longos
proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
}
Upgrade e Connection, a interface fica sem resposta após alguns segundos.
Se quiser uma camada extra de proteção antes do login do N8N:
apt install apache2-utils -y htpasswd -c /etc/nginx/.htpasswd seu_usuarioAdicione dentro do bloco location /:
auth_basic "N8N"; auth_basic_user_file /etc/nginx/.htpasswd;
location /webhook/ separado sem auth_basic para os endpoints de webhook.
location /webhook/ {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
# Sem auth_basic aqui
}
| Comando | O que faz |
|---|---|
docker ps | grep n8n | Ver se o container está rodando |
docker logs n8n -f | Ver logs em tempo real |
docker restart n8n | Reiniciar o container |
docker stop n8n | Parar o container |
docker start n8n | Iniciar o container parado |
docker rm -f n8n | Remover o container (dados no volume ficam) |
Rode novamente o comando docker run da instalação — o volume n8n_data preserva todos os workflows e credenciais.
Os dados ficam no volume Docker. Para exportar:
docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine tar czf /backup/n8n_backup.tar.gz -C /data .Para restaurar:
docker run --rm -v n8n_data:/data -v $(pwd):/backup alpine tar xzf /backup/n8n_backup.tar.gz -C /data# Exportar todos os workflows para JSON docker exec n8n n8n export:workflow --all --output=/tmp/workflows.json docker cp n8n:/tmp/workflows.json ./workflows.json # Importar workflows de um arquivo docker cp ./workflows.json n8n:/tmp/workflows.json docker exec n8n n8n import:workflow --input=/tmp/workflows.json
# 1. Criar e testar o workflow no editor visual # 2. Ativar o toggle "Active" quando pronto # 3. Monitorar as primeiras execuções docker logs n8n -f --since=10m # 4. Verificar execuções com erro na interface # Workflows → Executions → filtrar por "Error" # 5. Fazer backup antes de atualizações docker exec n8n n8n export:workflow --all --output=/tmp/backup.json
| Expressão | O que faz |
|---|---|
{{ $json.campo }} | Campo do item atual |
{{ $json.lista[0].campo }} | Primeiro item de uma lista aninhada |
{{ $('Node').first().json.campo }} | Primeiro item de um node específico |
{{ $now.toISO() }} | Data/hora atual em ISO 8601 |
{{ $now.toFormat('dd/MM/yyyy HH:mm') }} | Data formatada em PT-BR |
{{ $json.valor ?? 'padrão' }} | Valor ou fallback se nulo |
{{ $json.numero.toFixed(2) }} | Número com 2 casas decimais |
{{ $json.texto.toUpperCase() }} | Texto em maiúsculas |
{{ $json.texto.includes('palavra') }} | Verifica se texto contém substring |
{{ $vars.MINHA_CHAVE }} | Variável de ambiente do container |
| Categoria | Nodes |
|---|---|
| Triggers | Webhook, Schedule Trigger, Email Trigger, Manual Trigger |
| HTTP / APIs | HTTP Request, GraphQL, RSS Feed, FTP |
| Lógica | IF, Switch, Merge, Loop Over Items, Wait, Stop and Error |
| Transformação | Set, Edit Fields, Filter, Sort, Limit, Remove Duplicates, Code |
| Banco de dados | Postgres, MySQL, SQLite, Redis, MongoDB |
| Comunicação | Send Email, Telegram, Slack, Discord, WhatsApp |
| Arquivos | Read/Write Files, Extract from File, Convert to File, Compression |
| Utilidades | Respond to Webhook, Execute Command, SSH, Crypto, HTML Extract |
| Variável | Valor de exemplo | Para que serve |
|---|---|---|
N8N_HOST | n8n.seudominio.com | Hostname público |
N8N_PROTOCOL | https | Protocolo para links internos |
WEBHOOK_URL | https://n8n.seudominio.com/ | Base URL dos webhooks |
GENERIC_TIMEZONE | America/Belem | Timezone para Schedule nodes |
N8N_BASIC_AUTH_ACTIVE | true | Ativa login com usuário/senha |
N8N_BASIC_AUTH_USER | admin | Usuário do login básico |
N8N_BASIC_AUTH_PASSWORD | senha_forte | Senha do login básico |
EXECUTIONS_DATA_PRUNE | true | Apaga execuções antigas automaticamente |
EXECUTIONS_DATA_MAX_AGE | 168 | Horas para manter histórico (168 = 7 dias) |
--restart unless-stopped configuradon8n_data)127.0.0.1N8N_HOST, N8N_PROTOCOL e WEBHOOK_URL definidasGENERIC_TIMEZONE