Saudações.
Esse tutorial é um guia rápido de instalação do N8N versão 2 modo fila com taskrunners.
Pré-requisitos (constam em outros artigos aqui do blog):
- Instalação do Linux (Debian);
- Internet no servidor (sua VPS ou host);
- Docker CE instalado;
- Traefik como proxy reverso;
1 – Sobre N8N versão 2
O N8N (eni eiti eni) é um sistema de construção de automações no-code e low-code usando fluxos visuais, ligando visualmente componentes uns aos outros para criar programas.
A versão 2 implementou algumas mudanças, entre elas, a mais drástica foi a separação da execução de códigos Python e Javascript em containers separados de sandbox que ele nomeou como taskrunners.
Diagrama de relação entre serviços (containers) na versão 2:

A estrutura do WordPress é organizada em três camadas principais:
Com isso a estrutura de containers ficou assim:
- editor (main): Roda o núcleo do N8N, gestão completa e disparo de eventos (triggers);
- webhook: Roda o servidor web (HTTP) para disparo de eventos baseados na chamada de URLs e Webhooks (webhook trigger, form trigger);
- worker: Detecta o disparo de eventos e inicia a execução do workflow node a node, é o serviço que faz o trabalho pesado, todos os nodes do tipo code de Javascript e Python são enviados para execução no taskrunner;
- taskrunner: Se conecta ao worker para receber trabalhos de execução de códigos Javascript e Python, retorna os dados gerados e informações da execução;
- redis: Provê o canal de comunicação pub-sub entre todos os serviços acima e serve de cache de dados;
- postgresql: Provê o banco de dados persistente para cadastro de tudo (logins, credenciais, workflows, logs de execução, etc).
O serviço de webhook é opcional mas altamente recomendado para separar a carga de entrada das webhooks do editor, assim o editor fica com recursos reservados à administração do N8N enquanto que o webhook pode escalar por meio de réplicas.
Os containers dos 6 serviços tem diferentes naturezas de escalonamento:
- editor (main): Por padrão não escala, não replicável, pode escalar por meio de licença especial que permite o ambiente multi-main que balanceia a carga HTTP das ações administrativas. Devido ao fato do main rodar o núcleo duro do N8N que dispara quase todos os tipos de triggers das automações, ao rodar várias instâncias do editor uma delas será eleita a principal (master) para assumir a tarefa de disparo de triggers enquanto as demais atual apenas como balanceamento de carga das chamadas ao backend vindas do frontend;
- webhook: Replicável, o balanceamento de conexões de entrada é feito pelo Swarm e em casos mais avançados por cluster de proxy reverso;
- worker: Replicável, o balanceamento da carga é feita internamente entre os workers que disputam serviços na mensageria do redis;
- taskrunner: Replicável, o taskrunner requer o endereço do worker a qual ele se conectará e portanto o balanceamento é feito pelo Swarm;
- redis: Não replicável, todos os containers do N8N precisam se comunicar por ele, para escalar o redis é necessário montar um cluster redis;
- postgres: Não replicável, semelhante ao redis, requer cluster postgres separado;
2 – Preparativos
Nesse capítulo vou executar o N8N parte por parte para ambiente de estudos das partes isoladamente.
2.1 – Configurações
Personalize a variável EMAIL para que o LetsEncrypt funcione corretamente. Vou salvar o email de contato no arquivo /etc/email do host:
# Email de registro no letsencrypt
EMAIL="voce@seudominio.com.br";
# Gravar no arquivo para consulta
echo "$EMAIL" > /etc/email;
2.2 – Rede Docker
Rede Docker para containers do N8N:
docker network create \
-d bridge \
\
-o "com.docker.network.bridge.name"="br-net-public" \
-o "com.docker.network.bridge.enable_icc"="true" \
-o "com.docker.network.driver.mtu"="1500" \
\
--subnet 10.249.0.0/16 --gateway 10.249.255.254 \
\
network_public;
2.3 – Proxy Reverso – Traefik
Container do Traefik para proxy reverso com HTTPs automático:
#!/bin/bash
# Variaveis
NAME=traefik-app;
LOCAL=$NAME.intranet.br;
EMAIL="root@intranet.br";
[ -f /etc/email ] && EMAIL=$(head -1 /etc/email);
# Imagem
IMAGE=traefik:latest;
docker pull $IMAGE;
# Diretorio de dados persistentes
DATADIR=/storage/traefik-app;
mkdir -p $DATADIR/letsencrypt;
mkdir -p $DATADIR/logs;
mkdir -p $DATADIR/config;
# Renovar/rodar:
docker rm -f $NAME 2>/dev/null;
docker run \
-d --restart=always \
--name $NAME -h $LOCAL \
--tmpfs /run:rw,noexec,nosuid,size=2m \
--tmpfs /tmp:rw,noexec,nosuid,size=2m \
--read-only \
--cpus="8.0" --memory=4g --memory-swap=4g \
\
--network network_public \
\
-p 80:80 \
-p 443:443 \
\
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v $DATADIR/letsencrypt:/etc/letsencrypt \
-v $DATADIR/config:/etc/traefik \
-v $DATADIR/logs:/logs \
\
$IMAGE \
\
--global.checkNewVersion=false \
--global.sendAnonymousUsage=false \
\
--api.insecure=true \
\
--log.level=INFO \
--log.filePath=/logs/error.log \
\
--accessLog.filePath=/logs/access.log \
\
--entrypoints.web.address=:80 \
--entrypoints.web.http.redirections.entryPoint.to=websecure \
--entrypoints.web.http.redirections.entryPoint.scheme=https \
--entrypoints.web.http.redirections.entryPoint.permanent=true \
--entrypoints.websecure.address=:443 \
\
--providers.docker=true \
--providers.file.directory=/etc/traefik \
\
--certificatesresolvers.letsencrypt.acme.email=$EMAIL \
--certificatesresolvers.letsencrypt.acme.storage=/etc/letsencrypt/acme.json \
--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web;
2.4 – Banco de dados PostgreSQL
Vamos criar um banco de dados PostgreSQL chamado “n8n-pgsql“:
# Credenciais de acesso ao PG
POSTGRES_USER="postgres";
POSTGRES_PASSWORD="tulipasql";
POSTGRES_DB="n8n";
# Pasta para o volume
mkdir -p /storage/n8n-pgsql;
chown -R 999:999 /storage/n8n-pgsql;
# Rodar:
docker pull pgvector/pgvector:pg18-trixie;
docker run \
-d --restart=always \
--name n8n-pgsql -h n8n-pgsql.intranet.br \
--read-only --cpus="2.0" --memory=2g --memory-swap=2g --shm-size=1g \
\
--network network_public \
\
--tmpfs /run:rw,noexec,nosuid,size=128m \
--tmpfs /tmp:rw,noexec,nosuid,size=128m \
\
-v /storage/n8n-pgsql:/var/lib/postgresql/data \
\
-e POSTGRES_USER=$POSTGRES_USER \
-e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
-e POSTGRES_DB=$POSTGRES_DB \
-e PGDATA=/var/lib/postgresql/data/pgdata \
\
--health-cmd="pg_isready -U postgres" \
--health-interval=5s \
--health-timeout=5s \
--health-retries=10 \
\
--entrypoint "docker-entrypoint.sh" \
\
pgvector/pgvector:pg18-trixie \
postgres \
--max_connections=8192 \
--wal_level=minimal \
--max_wal_senders=0 \
--port=5432;
2.5 – Redis
O Redis é vital para o N8N, vamos criar o container chamado “n8n-redis“:
# Pasta de persistencia RDB e AOF:
mkdir -p /storage/n8n-redis;
chown -R 999:999 /storage/n8n-redis;
# Baixar imagem atualizada do Redis (https://hub.docker.com/_/redis):
docker pull redis:latest;
# Remover container atual:
docker rm -f n8n-redis 2>/dev/null;
# Criar container do redis:
docker run \
-d --restart=always \
--name n8n-redis -h n8n-redis.intranet.br \
--read-only --cpus="1.0" --memory=1g --memory-swap=1g \
\
--network network_public \
\
-v /storage/n8n-redis:/data \
-w /data \
\
--health-cmd="redis-cli ping" \
--health-interval=1s \
--health-timeout=3s \
\
redis:latest \
redis-server \
--tcp-backlog 8192 --tcp-keepalive 30 --timeout 0 \
--dir /data --save 16 1 --save 12 10 --save 6 100 \
--rdbcompression no --appendonly yes --appendfsync everysec;
3 – Variáveis de ambiente
O N8N possui uma vastidão de variáveis de ambientes mas elas podem ser divididas de acordo com suas finalidades e quais serviços precisam delas.
Variáveis com valor semelhante ao valor padrão estarão em AZUL e os valores alterados e personalizados de VERMELHO.
Você pode omitir todas as variáveis em AZUL sem problemas, isso economiza espaço na configuração.
3.1 – Modo fila (1 variável)
O antigo modo simples baseado no sqlite foi substituído pelo modo fila que faz uso do Redis e PostgreSQL por meio da técnica Claim Check Pattern (sinais em tempo real no Redis pub/sub e dados de transações no SQL).
Dados para acesso ao Redis e PG do modelo fila foram definidos na criação dos containers no capítulo 2.
Usadas pelo editor, webhook e worker, não são usadas pelo task-runner.
| Variável | Valor |
| EXECUTIONS_MODE | queue |
| EXECUTIONS_TIMEOUT Padrão -1 (eterno), limite em segundos, evita acumulo de workflows travados Valor em segundos | 1800 |
| EXECUTIONS_TIMEOUT_MAX Recomendável 7200 (2h) para execuções longas Valor em segundos | 3600 |
3.2 – Acesso a Redis (1 variável)
Usados pelo editor, webhook e worker, não é usado pelo task-runner.
Variáveis do Redis:
| Variável | Valor |
| QUEUE_BULL_REDIS_HOST | n8n-redis |
| QUEUE_BULL_REDIS_CLUSTER_NODES Quando houver cluster redis, sintaxe: redis-1:6379,redis-2:6379 | (vazio) |
| QUEUE_BULL_REDIS_DNS_LOOKUP_STRATEGY | LOOKUP |
| QUEUE_BULL_REDIS_PORT | 6379 |
| QUEUE_BULL_REDIS_TLS | false |
| QUEUE_BULL_REDIS_DB Altere para usar um Redis compartilhado com outros sistemas | 0 |
| QUEUE_BULL_REDIS_KEEP_ALIVE | false |
| QUEUE_BULL_REDIS_KEEP_ALIVE_DELAY | 5000 |
| QUEUE_BULL_REDIS_KEEP_ALIVE_INTERVAL | 5000 |
| QUEUE_BULL_REDIS_RECONNECT_ON_FAILOVER | true |
| QUEUE_BULL_REDIS_USERNAME | (vazio) |
| QUEUE_BULL_REDIS_PASSWORD | (vazio) |
| QUEUE_BULL_REDIS_TIMEOUT_THRESHOLD | 10_000 |
| QUEUE_BULL_REDIS_SLOT_REFRESH_TIMEOUT | 1_000 |
| QUEUE_BULL_REDIS_SLOT_REFRESH_INTERVAL | 5_000 |
| QUEUE_BULL_PREFIX Prefixo das chaves de cache | bull |
| N8N_GRACEFUL_SHUTDOWN_TIMEOUT | 30 |
| QUEUE_BULL_REDIS_DUALSTACK Se alterado para true, permite uso de IPv6 se presente | false |
| QUEUE_HEALTH_CHECK_ACTIVE Mude para true se o Redis sofre risco de sair do ar | false |
| QUEUE_HEALTH_CHECK_PORT | 5678 |
| N8N_REDIS_KEY_PREFIX | n8n |
| QUEUE_WORKER_LOCK_DURATION | 60_000 |
| QUEUE_WORKER_LOCK_RENEW_TIME | 10_000 |
| QUEUE_WORKER_STALLED_INTERVAL | 30_000 |
3.3 – Acesso a Postgres (3 variáveis)
| Variável | Valor |
| DB_TYPE | postgresdb |
| DB_POSTGRESDB_HOST | n8n-pgsql |
| DB_POSTGRESDB_PORT | 5432 |
| DB_POSTGRESDB_DATABASE | n8n |
| DB_POSTGRESDB_USER | postgres |
| DB_POSTGRESDB_PASSWORD | tulipasql |
| DB_POSTGRESDB_SCHEMA | public |
| DB_POSTGRESDB_POOL_SIZE Tuning: Recomendo aumentar para 32 | 2 |
| DB_POSTGRESDB_SSL_ENABLED | false |
| DB_POSTGRESDB_SSL_CA | (vazio) |
| DB_POSTGRESDB_SSL_CERT | (vazio) |
| DB_POSTGRESDB_SSL_KEY | (vazio) |
| DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED | true |
| DB_POSTGRESDB_CONNECTION_TIMEOUT Valor em milissegundos, timeout com o PG | 20_000 |
| DB_POSTGRESDB_IDLE_CONNECTION_TIMEOUT Valor em milissegundos, encerra conexões adicionais inativas | 30_000 |
| DB_POSTGRESDB_STATEMENT_TIMEOUT Valor em milissegundos, limite de execução de uma query | 300_000 |
O N8N não envia operações de vaccum para o postgres, lembre de fazer essa rotina mensalmente.
3.4 – Opções globais (2 variáveis)
Variáveis de uso global e necessárias para todos os serviços: editor, webhook, worker, e task-runner.
| Variável | Valor |
| GENERIC_TIMEZONE Padrão: America/New_York | America/Sao_Paulo |
| TZ Padrão herdado do sistema local | America/Sao_Paulo |
3.5 – Opções gerais (4 variáveis)
Variáveis usadas pelo editor, webhook e worker, não são usadas no task-runner.
| Variável | Valor |
| N8N_PATH | / |
| N8N_DEFAULT_LOCALE | en |
| N8N_ENCRYPTION_KEY Padrão vazio, usado para protege credenciais | tulipa |
| NODE_ENV Requer especificação, opções: test, development ou production | production |
| N8N_DIAGNOSTICS_ENABLED Padrão true mas não vamos enviar dados para a N8N | false |
| N8N_USER_FOLDER Padrão $HOME do usuário node | /data |
| N8N_LOG_LEVEL | info |
| N8N_LOG_CRON_ACTIVE_INTERVAL | 0 |
| N8N_LOG_FILE_COUNT_MAX | 100 |
| N8N_LOG_FILE_SIZE_MAX | 16 |
| N8N_LOG_FILE_LOCATION | logs/n8n.log |
| N8N_LOG_OUTPUT | console,file |
| N8N_LOG_FORMAT | text |
| N8N_LOG_SCOPES | (vazio) |
| N8N_DIAGNOSTICS_POSTHOG_API_KEY | (chave da n8n) |
| N8N_DIAGNOSTICS_POSTHOG_API_HOST | (url posthog) |
| N8N_DIAGNOSTICS_CONFIG_FRONTEND | (url da n8n) |
| N8N_DIAGNOSTICS_CONFIG_BACKEND | (url da n8n) |
| N8N_METRICS | true |
| N8N_METRICS_PREFIX | n8n_ |
| N8N_METRICS_INCLUDE_DEFAULT_METRICS | true |
| N8N_METRICS_INCLUDE_WORKFLOW_ID_LABEL | false |
| N8N_METRICS_INCLUDE_NODE_TYPE_LABEL | false |
| N8N_METRICS_INCLUDE_CREDENTIAL_TYPE_LABEL | false |
| N8N_METRICS_INCLUDE_API_ENDPOINTS | false |
| N8N_METRICS_INCLUDE_API_PATH_LABEL | false |
| N8N_METRICS_INCLUDE_API_METHOD_LABEL | false |
| N8N_METRICS_INCLUDE_API_STATUS_CODE_LABEL | false |
| N8N_METRICS_INCLUDE_CACHE_METRICS | false |
| N8N_METRICS_INCLUDE_MESSAGE_EVENT_BUS_METRICS | false |
| N8N_METRICS_INCLUDE_QUEUE_METRICS | false |
| N8N_METRICS_QUEUE_METRICS_INTERVAL | 20 |
| N8N_METRICS_ACTIVE_WORKFLOW_METRIC_INTERVAL | 60 |
| N8N_METRICS_INCLUDE_WORKFLOW_NAME_LABEL | false |
| N8N_METRICS_INCLUDE_WORKFLOW_STATISTICS | false |
| N8N_METRICS_WORKFLOW_STATISTICS_INTERVAL | 300 |
| N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS | true |
3.6 – Opções de servidor http (4 variáveis)
Variáveis usadas apenas pelos serviços que abrem a porta HTTP para webhooks.
Usados pelo editor e webhook, não é usado pelo worker e task-runner.
| Variável | Valor |
| WEBHOOK_URL | (a explicar) |
| N8N_HOST | (a explicar) |
| N8N_PORT | 5678 |
| N8N_LISTEN_ADDRESS | :: |
| N8N_PROTOCOL Padrão: http | https |
| N8N_PROXY_HOPS Padrão: 0 | 1 |
| N8N_SSL_CERT | (vazio) |
| N8N_SSL_KEY | (vazio) |
| N8N_PAYLOAD_SIZE_MAX | 16 |
| N8N_FORMDATA_FILE_SIZE_MAX | 200 |
3.6 – Opções exclusivas do editor (4 variáveis)
Usados somente pelo editor (frontend e backend).
| Variável | Valor |
| OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS | true |
| N8N_EDITOR_BASE_URL | (a explicar) |
| N8N_DISABLE_UI | false |
| N8N_AI_ENABLED | false |
| N8N_AI_PROVIDER | openai |
| N8N_AI_OPENAI_API_KEY | (vazio) |
| N8N_AI_TIMEOUT_MAX | 3600000 |
| N8N_AI_ALLOW_SENDING_PARAMETER_VALUES | true |
| N8N_AI_PERSIST_BUILDER_SESSIONS | false |
| N8N_ENDPOINT_REST | rest |
| N8N_ENDPOINT_FORM | form |
| N8N_ENDPOINT_FORM_TEST | form-test |
| N8N_ENDPOINT_FORM_WAIT | form-waiting |
| N8N_ENDPOINT_WEBHOOK | webhook |
| N8N_ENDPOINT_WEBHOOK_TEST | webhook-test |
| N8N_ENDPOINT_WEBHOOK_WAIT | webhook-waiting |
| N8N_ENDPOINT_MCP | mcp |
| N8N_ENDPOINT_MCP_TEST | mcp-test |
| N8N_DISABLE_PRODUCTION_MAIN_PROCESS | false |
| N8N_ADDITIONAL_NON_UI_ROUTES | (vazio) |
| N8N_ENDPOINT_HEALTH | /healthz |
| EXECUTIONS_DATA_HARD_DELETE_BUFFER Valor em horas | 1 |
| EXECUTIONS_DATA_MAX_AGE Valor em horas | 336 |
| EXECUTIONS_DATA_PRUNE | true |
| EXECUTIONS_DATA_PRUNE_HARD_DELETE_INTERVAL Valor em minutos | 15 |
| EXECUTIONS_DATA_PRUNE_MAX_COUNT | 10_000 |
| EXECUTIONS_DATA_PRUNE_SOFT_DELETE_INTERVAL Valor em minutos | 60 |
| EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS | true |
| N8N_VERSION_NOTIFICATIONS_ENABLED Desativa notificações sobre novas versões do N8N | false |
| N8N_VERSION_NOTIFICATIONS_ENDPOINT | (url da n8n) |
| N8N_VERSION_NOTIFICATIONS_WHATS_NEW_ENABLED Desativa notificações de novos recursos dos updates recentes | false |
| N8N_VERSION_NOTIFICATIONS_WHATS_NEW_ENDPOINT | (url da n8n) |
| N8N_VERSION_NOTIFICATIONS_INFO_URL | (url da n8n) |
N8N_PUBLIC_API_DISABLED | false |
| N8N_PUBLIC_API_ENDPOINT | api |
| N8N_PUBLIC_API_SWAGGERUI_DISABLED | true |
3.7 – Opções do editor e worker (3 variáveis)
Usados pelo editor e worker, não é usado pelo webhook e task-runner.
| Variável | Valor |
| N8N_RUNNERS_MODE | external |
| EXECUTIONS_DATA_SAVE_ON_ERROR Opções: all, none, padrão all | all |
| EXECUTIONS_DATA_SAVE_ON_PROGRESS Padrão: false | true |
| EXECUTIONS_DATA_SAVE_ON_SUCCESS Opções: all, none, padrão none | all |
3.8 – Opções exclusivas do worker (2 variáveis)
Variáveis usadas somente pelo worker.
| Variável | Valor |
| N8N_RUNNERS_BROKER_LISTEN_ADDRESS Padrão 127.0.0.1, não escuta na rede local | 0.0.0.0 |
| N8N_RUNNERS_ENABLED Legado da v2, descontinuada na v2 e hard-coded como true | true |
3.9 – Opções exclusivas do task-runner (1 variável)
Variáveis usadas pelo task-runner.
| Variável | Valor |
| N8N_RUNNERS_TASK_BROKER_URI | (a explicar) |
| N8N_RUNNERS_HEALTH_CHECK_SERVER_ENABLED | true |
| N8N_RUNNERS_HEALTH_CHECK_SERVER_HOST | true |
| N8N_RUNNERS_HEALTH_CHECK_SERVER_PORT | true |
| N8N_RUNNERS_GRANT_TOKEN | true |
| N8N_RUNNERS_MAX_PAYLOAD Padrão: 1024 * 1024 * 1024 = 1.073.741.824 bytes (1 GB) | 1073741824 |
| N8N_RUNNERS_MAX_CONCURRENCY | 10 |
| N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT | 0 |
| N8N_RUNNERS_PATH | /runners |
| N8N_RUNNERS_BROKER_PORT | 5679 |
| N8N_RUNNERS_MAX_OLD_SPACE_SIZE | (vazio) |
| N8N_RUNNERS_TASK_TIMEOUT | 300 |
| N8N_RUNNERS_TASK_REQUEST_TIMEOUT | 60 |
| N8N_RUNNERS_HEARTBEAT_INTERVAL | 30 |
| N8N_RUNNERS_INSECURE_MODE | false |
| N8N_RUNNERS_LAUNCHER_LOG_LEVEL | debug |
3.9 – Opções do worker e task-runner (1 variável)
Usados pelo worker e task-runner.
| Variável | Valor |
| N8N_RUNNERS_AUTH_TOKEN Padrão vazio, especificar por segurança | tulipa |
4 – Entendendo o Task-Runner
O runner executará em container separado, esse modo é chamado de EXTERNAL.
Diferenças:
- internal: O task-runner é executado como processo filho do processo que executa o workflow;
- Vantagens: simples, rápido;
- Desvantagens: inseguro, pode quebrar o sistema inteiro;
- external: O task-runner é executado em serviço separado e isolado, recebe apenas os dados objetivos para execução de código JS e PY e cria um sandbox;
- Vantagens: seguro, isolado, resiliente;
- Desvantagens: lento, podem induzir uma demora de até 3 segundos na execução do workflow;
Vou abordar o modo external pois é a tendência de evolução do N8N.
Quando o worker é iniciado com a configuração N8N_RUNNERS_MODE=external ele precisará abrir a porta 5679/tcp para atuar como servidor broker:
- Porta em N8N_RUNNERS_BROKER_PORT=5679;
- IP de escuta em N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0;
O worker não poderá executar nenhum “node code” até que 1 runner se concte a ele.
Essa lógica permite que os containers dos runners trabalhem remotamente em servidores diferentes dos servidores de worker, editor e webhook.
O task-runner precisa saber o endereço IP e porta do worker a qual ele se conectará para coletar trabalho, o endereço é definido na variável:
- N8N_RUNNERS_TASK_BROKER_URI, exemplo: http://n8n-worker:5679
Vários runners podem apontar para um mesmo worker.
O ideal é trabalhar com no mínimo 2 réplicas de workers e 4 réplicas de runners.
5 – Endereços de acesso
O N8N pode ser executado em ambiente privado sem HTTPs ou em ambiente público com homologação completa (HTTPs + Certificado reconhecido globalmente).
5.1 – Executando N8N em ambiente privado
As seguintes variáveis devem ser configuradas para acessar o N8N diretamente na porta HTTP (sem criptografia) e sem URL pública:
| Variável | Valor |
| N8N_HOST IPv4, IPv6 ou nome de DNS do servidor | 192.168.14.199 |
| WEBHOOK_URL URL do servidor webhook | http://192.168.14.199 |
| N8N_PROXY_HOPS Sem proxy-reverso entre o navegador e o N8N | 0 |
| N8N_EDITOR_BASE_URL URL para geração de links nas automações | http://192.168.14.199 |
O acesso será na porta HTTP direta do N8N (N8N_PORT=5678).
Exemplo de acesso ao editor: http://192.168.14.199:5678/
O container de webhook precisará de outra porta redirecionada para a mesma porta 5678 ou ser publicada por meio de um túnel (CloudFlare, Akamai, webhook-relay).
5.2 – Executando N8N em ambiente público
Será necessário configurar o DNS corretamente, os seguintes nomes serão necessários:
| Nome de DNS (FQDN) | Serviço |
| n8n.seudominio.com.br | Editor do N8N – Administração |
| ws.seudominio.com.br | Webhook – Servidor HTTP das automações |
As variáveis devem ser preenchidas assim:
| Variável | Valor |
| N8N_HOST IPv4, IPv6 ou nome de DNS do servidor | n8n.seudominio.com.br |
| WEBHOOK_URL URL do servidor webhook | https://ws.seudominio.com.br |
| N8N_PROXY_HOPS Com proxy-reverso entre o navegador e o N8N | 1 |
| N8N_EDITOR_BASE_URL URL para geração de links nas automações | https://n8n.seudominio.com.br |
O acesso será na porta HTTPs (tcp/443) do proxy-reverso (Traefik) que encaminhará para o container do editor na porta http 5678 (N8N_PORT=5678).
Exemplo de acesso ao editor: https://n8n.seudominio.com.br
Exemplo de acesso ao webhook: https://ws.seudominio.com.br
5.3 – Sufixos dos serviços webhook
O servidor de webhook responde pelas URLs providas pelas automações e faz a separação por pasta na URL, acessos:
- Trigger webhook: Sufixo padrão “webhook“, pode ser personalizado na variável N8N_ENDPOINT_WEBHOOK.
- URL: https://ws.seudominio.com.br/webhook/
- Alternativa: definir como N8N_EDITOR_BASE_URL=v1, fica assim:
- URL: https://ws.seudominio.com.br/v1/
- Trigger MCP-Server: Sufixo padrão “mcp“, pode ser personalizado na variável N8N_ENDPOINT_MCP.
- URL: https://ws.seudominio.com.br/mcp/
- Trigger Form: Sufixo padrão “form“, pode ser personalizado na variável N8N_ENDPOINT_FORM.
- URL: https://ws.seudominio.com.br/form/
Não altere a menos que seja proposital e planejado pois pode quebrar automações antigas e ou importadas.
6 – Executando o N8N
Vamos partir para a criação dos serviços com tudo que organizamos até aqui usando o N8N em uma URL pública (HTTPs provido por Traefik e LetsEncrypt).
6.1 – Pasta do projeto
Crie uma pasta para o projeto, nele iremos colocar todos os arquivos necessários para rodar independente do estilo (eu prefiro “docker run”).
Diretório: /root/n8n-deploy:
# Diretorio do projeto
mkdir /root/n8n-deploy;
6.2 – Pasta dos volumes
Você pode usar qualquer volume em qualquer diretório, o importante é fixar o UID/GID da pasta principal do volume para 1000 (usuário node dentro do container).
Arquivo /root/n8n-deploy/run-11-datadir.sh
# Pasta para volume dos containers
mkdir -p /storage/n8n-app;
mkdir -p /storage/n8n-app/editor;
mkdir -p /storage/n8n-app/worker;
mkdir -p /storage/n8n-app/webhook;
mkdir -p /storage/n8n-app/runner;
# Corrigir permissoes:
chown -R 1000:1000 /storage/n8n-app;
6.3 – Versão do N8N
Vou usar a versão estável 2.11.3 na tag docker.n8n.io/n8nio/n8n:2.11.3, é importante evitar a tag “docker.n8n.io/n8nio/n8n:latest” pois podem haver updates que quebram funcionalidades.
Imagens:
- N8N: docker.n8n.io/n8nio/n8n:2.11.3
- Runner: n8nio/runners:2.11.3
Arquivo /root/n8n-deploy/run-12-pull-image.sh
# Baixar imagem docker do N8N
docker pull docker.n8n.io/n8nio/n8n:2.11.3;
# Baixar imagem docker do Runner
docker pull n8nio/runners:2.11.3;
6.4 – Arquivos .env
Vamos criar um arquivo .env para cada grupo de variáveis baseado nos serviços que farão leitura deles, assim teremos uma configuração mais pontual e segura.
Variáveis que afetam todos os serviços. Arquivo /root/n8n/.env-n8n-global
GENERIC_TIMEZONE=America/Sao_Paulo
TZ=America/Sao_PauloVariáveis de todos os serviços para modo queue. Arquivo /root/n8n/.env-n8n-queue
EXECUTIONS_MODE=queue
EXECUTIONS_TIMEOUT=1800Variáveis de acesso ao Redis. Arquivo /root/n8n/.env-n8n-redis
QUEUE_BULL_REDIS_HOST=n8n-redisVariáveis de acesso ao Postgres. Arquivo /root/n8n/.env-n8n-postgres
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=n8n-pgsql
DB_POSTGRESDB_PASSWORD=tulipasqlVariáveis de todos os serviços do N8N. Arquivo /root/n8n/.env-n8n-services
N8N_ENCRYPTION_KEY=tulipa
NODE_ENV=production
N8N_DIAGNOSTICS_ENABLED=false
N8N_USER_FOLDER=/data
N8N_METRICS=trueVariáveis exclusivas do editor. Arquivo /root/n8n/.env-n8n-editor
N8N_EDITOR_BASE_URL=https://n8n.seudominio.com.br/
N8N_VERSION_NOTIFICATIONS_ENABLED=false
N8N_VERSION_NOTIFICATIONS_WHATS_NEW_ENABLED=false
N8N_PUBLIC_API_SWAGGERUI_DISABLED=trueVariáveis de serviços WEB (editor e webhook). Arquivo /root/n8n/.env-n8n-web
WEBHOOK_URL=https://ws.seudominio.com.br/
N8N_HOST=n8n.seudominio.com.br
N8N_PROTOCOL=https
N8N_PROXY_HOPS=1Variáveis dos serviços de workflow (editor e worker). Arquivo /root/n8n/.env-n8n-core
N8N_RUNNERS_MODE=external
EXECUTIONS_DATA_SAVE_ON_PROGRESS=true
EXECUTIONS_DATA_SAVE_ON_SUCCESS=allVariáveis exclusivas do worker. Arquivo /root/n8n/.env-n8n-worker
N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
N8N_RUNNERS_ENABLED=trueVariáveis exclusivas do task-runner. Arquivo /root/n8n/.env-n8n-runner
N8N_RUNNERS_TASK_BROKER_URI=http://n8n-worker:5679Variáveis para comunicação entre editor, worker e task-runner,
Arquivo /root/n8n/.env-n8n-tasks
N8N_RUNNERS_AUTH_TOKEN=tulipa6.5 – Executando o editor (main)
Script no arquivo /root/n8n/run-21-editor.sh
# Nome de DNS para acesso HTTPs
# - Importar da variavel N8N_HOST no arquivo .env
. /root/n8n/.env-n8n-web;
# Remover container atual:
docker rm -f n8n-editor 2>/dev/null;
# Rodando:
docker run -d \
--name n8n-editor -h n8n-editor.intranet.br \
--cpus=4 --memory=4g --memory-swap=4g --shm-size=1g \
--tmpfs /run:rw,noexec,nosuid,size=512m \
--tmpfs /tmp:rw,noexec,nosuid,size=512m \
\
--network network_public \
\
--env-file /root/n8n/.env-n8n-global \
--env-file /root/n8n/.env-n8n-queue \
--env-file /root/n8n/.env-n8n-redis \
--env-file /root/n8n/.env-n8n-postgres \
--env-file /root/n8n/.env-n8n-services \
\
--env-file /root/n8n/.env-n8n-editor \
--env-file /root/n8n/.env-n8n-web \
--env-file /root/n8n/.env-n8n-core \
--env-file /root/n8n/.env-n8n-tasks \
\
-v /storage/n8n-app/editor:/data \
\
--label "traefik.enable=true" \
--label "traefik.http.routers.n8n-editor.rule=Host(\`$N8N_HOST\`)" \
--label "traefik.http.routers.n8n-editor.entrypoints=web,websecure" \
--label "traefik.http.routers.n8n-editor.tls=true" \
--label "traefik.http.routers.n8n-editor.tls.certresolver=letsencrypt" \
--label "traefik.http.services.n8n-editor.loadbalancer.server.port=5678" \
\
docker.n8n.io/n8nio/n8n:2.11.3;
6.6 – Executando o webhook
Execução muito parecida com a do editor, difere pelo comando “webhook” no container. A o nome para redirecionamento no Traefik será extraido da variável WEBHOOK_URL.
Script no arquivo /root/n8n/run-22-webhook.sh
# Nome de DNS para acesso HTTPs
# - Importar da variavel N8N_HOST no arquivo .env
. /root/n8n/.env-n8n-web;
FQDN_WEBHOOK=$(echo $WEBHOOK_URL | cut -f3 -d/);
# Remover container atual:
docker rm -f n8n-webhook 2>/dev/null;
# Rodando:
docker run -d \
--name n8n-webhook -h n8n-webhook.intranet.br \
--cpus=4 --memory=4g --memory-swap=4g --shm-size=1g \
--tmpfs /run:rw,noexec,nosuid,size=512m \
--tmpfs /tmp:rw,noexec,nosuid,size=512m \
\
--network network_public \
\
--env-file /root/n8n/.env-n8n-global \
--env-file /root/n8n/.env-n8n-queue \
--env-file /root/n8n/.env-n8n-redis \
--env-file /root/n8n/.env-n8n-postgres \
--env-file /root/n8n/.env-n8n-services \
\
--env-file /root/n8n/.env-n8n-web \
\
-v /storage/n8n-app/webhook:/data \
\
--label "traefik.enable=true" \
--label "traefik.http.routers.n8n-webhook.rule=Host(\`$FQDN_WEBHOOK\`)" \
--label "traefik.http.routers.n8n-webhook.entrypoints=web,websecure" \
--label "traefik.http.routers.n8n-webhook.tls=true" \
--label "traefik.http.routers.n8n-webhook.tls.certresolver=letsencrypt" \
--label "traefik.http.services.n8n-webhook.loadbalancer.server.port=5678" \
\
docker.n8n.io/n8nio/n8n:2.11.3 webhook;
6.7 – Executando o worker
O worker precisa se conectar ao Redis, Postgres e aguardar o Task-Runner se conectar nele. O container deve rodar o comando “worker“.
Script no arquivo /root/n8n/run-23-worker.sh
# Remover container atual:
docker rm -f n8n-worker 2>/dev/null;
# Rodando:
docker run -d \
--name n8n-worker -h n8n-worker.intranet.br \
--cpus=4 --memory=4g --memory-swap=4g --shm-size=1g \
--tmpfs /run:rw,noexec,nosuid,size=512m \
--tmpfs /tmp:rw,noexec,nosuid,size=512m \
\
--network network_public \
\
--env-file /root/n8n/.env-n8n-global \
--env-file /root/n8n/.env-n8n-queue \
--env-file /root/n8n/.env-n8n-redis \
--env-file /root/n8n/.env-n8n-postgres \
--env-file /root/n8n/.env-n8n-services \
\
--env-file /root/n8n/.env-n8n-core \
--env-file /root/n8n/.env-n8n-worker \
--env-file /root/n8n/.env-n8n-tasks \
\
-v /storage/n8n-app/worker:/data \
\
docker.n8n.io/n8nio/n8n:2.11.3 worker;
6.8 – Executando o task-runner
O task-runner requer uma atenção especial à variável N8N_RUNNERS_TASK_BROKER_URI que deve apontar para o nome do container do worker na porta 5679.
Script no arquivo /root/n8n/run-24-runner.sh
# Remover container atual:
docker rm -f n8n-runner 2>/dev/null;
# Rodando:
docker run -d \
--name n8n-runner -h n8n-runner.intranet.br \
--cpus=4 --memory=4g --memory-swap=4g --shm-size=1g \
--tmpfs /run:rw,noexec,nosuid,size=512m \
--tmpfs /tmp:rw,noexec,nosuid,size=512m \
\
--network network_public \
\
--env-file /root/n8n/.env-n8n-global \
\
--env-file /root/n8n/.env-n8n-runner \
--env-file /root/n8n/.env-n8n-tasks \
\
-v /storage/n8n-app/runner:/data \
\
n8nio/runners:2.11.3;
6.9 – Execução concluida
Agora todos os serviços estão rodando.
Exportando arquivos do tutorial em formato MarkDown.
Arquivo: /root/n8n/export-markdown.sh
# Exportar projeto em markdown
(
echo '# N8N v2 Deploy';
echo;
echo '## Arquivos ENV';
for envfile in /root/n8n/.env*; do
echo "### $envfile";
echo;
echo '```env'; cat $envfile; echo '```';
echo;
done;
echo;
echo '## Scripts';
for script in /root/n8n/run*; do
echo "### $script";
echo;
echo '```bash'; cat $script; echo '```';
echo;
done;
echo;
) > /root/n8n/STARTHERE.md;
7 – Primeiro contato
Após rodar os containers, abra o navegador no endereço https://n8n.seudominio.com.br para cadastrar o login de administrador.
Você pode automatizar esse setup de usuário administrador.
Arquivo /root/n8n/run-51-setup-admin.sh
# Nome de DNS para acesso HTTPs
# - Importar da variavel N8N_HOST no arquivo .env
. /root/n8n/.env-n8n-web;
# Dados do formulario
# Template JSON
JSON_DATA='{
"email": "admin@acme.com",
"firstName": "Acme",
"lastName": "Jobs",
"password": "Acme@123"
}';
echo "# Definir login administrativo:";
echo;
echo "# URL: https://$N8N_HOST/rest/owner/setup";
echo;
echo "$JSON_DATA";
echo;
curl -v \
-X POST \
-H 'Accept: application/json, text/plain, */*' \
-H 'Content-Type: application/json' \
-d "$JSON_DATA" \
"https://$N8N_HOST/rest/owner/setup";
8 – Stack para Docker Compose standalone
Agora vamos empacotar nosso setup para simplificar a implementação usarndo Docker Compose em um servidor sem swarm, ou seja, o Docker em standalone.
8.1 – Preparativos – Rede e Traefik
Nessa stack vamos colocar o Traefik (container traefik-app) e a rede Docker (network_public). Troque o e-mail voce@seudomino.com.br pelo seu e-mail verdadeiro.
Arquivo: /root/n8n-deploy/docker-compose-traefik.yml
networks:
network_public:
driver: bridge
driver_opts:
com.docker.network.bridge.name: "br-net-public"
com.docker.network.bridge.enable_icc: "true"
com.docker.network.driver.mtu: "1500"
ipam:
driver: default
config:
- subnet: 10.249.0.0/16
gateway: 10.249.255.254
services:
traefik-app:
image: traefik:latest
container_name: traefik-app
hostname: traefik-app.intranet.br
restart: always
cpus: 4
mem_limit: 4g
memswap_limit: 4g
shm_size: 1g
read_only: true
tmpfs:
- /run:rw,noexec,nosuid,size=2m
- /tmp:rw,noexec,nosuid,size=2m
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /storage/traefik-app/letsencrypt:/etc/letsencrypt
- /storage/traefik-app/config:/etc/traefik
- /storage/traefik-app/logs:/logs
networks:
- network_public
command:
# Global
- "--global.checkNewVersion=false"
- "--global.sendAnonymousUsage=false"
# API / Dashboard (acesso inseguro - use apenas em ambiente controlado)
- "--api.insecure=true"
# Logs de erro
- "--log.level=INFO"
- "--log.filePath=/logs/error.log"
# Logs de acesso
- "--accessLog.filePath=/logs/access.log"
# Entrypoint HTTP (porta 80) com redirect automático para HTTPS
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entryPoint.permanent=true"
# Entrypoint HTTPS (porta 443)
- "--entrypoints.websecure.address=:443"
# Providers
- "--providers.docker=true"
- "--providers.file.directory=/etc/traefik"
# Certificados Let's Encrypt via HTTP Challenge
- "--certificatesresolvers.letsencrypt.acme.email=voce@seudominio.com.br"
- "--certificatesresolvers.letsencrypt.acme.storage=/etc/letsencrypt/acme.json"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
8.1 – Básico – Versão stack dos scripts
Essa stack tem os mesmos argumentos dos scripts anteriores fazendo referência aos arquivos .env-* das variáveis de ambiente e usando volumes montados em /storage/.
Arquivo: /root/n8n/docker-compose.yml
networks:
network_public:
external: true
x-n8n-common: &n8n-common
image: docker.n8n.io/n8nio/n8n:2.11.3
restart: always
cpus: 4
mem_limit: 4g
memswap_limit: 4g
shm_size: 1g
tmpfs:
- /run:rw,noexec,nosuid,size=512m
- /tmp:rw,noexec,nosuid,size=512m
networks:
- network_public
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
services:
# ───────────────────────────────────────── PostgreSQL
n8n-pgsql:
image: pgvector/pgvector:pg18-trixie
container_name: n8n-pgsql
hostname: n8n-pgsql.intranet.br
restart: always
read_only: true
cpus: "2.0"
mem_limit: 2g
memswap_limit: 2g
shm_size: 1g
networks:
- network_public
tmpfs:
- /run:rw,noexec,nosuid,size=128m
- /tmp:rw,noexec,nosuid,size=128m
volumes:
- /storage/n8n-pgsql:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: tulipasql
POSTGRES_DB: n8n
PGDATA: /var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 5s
timeout: 5s
retries: 10
entrypoint: ["docker-entrypoint.sh"]
command:
- postgres
- --max_connections=8192
- --wal_level=minimal
- --max_wal_senders=0
- --port=5432
# ───────────────────────────────────────── Redis
n8n-redis:
image: redis:latest
container_name: n8n-redis
hostname: n8n-redis.intranet.br
restart: always
read_only: true
cpus: "1.0"
mem_limit: 1g
memswap_limit: 1g
working_dir: /data
networks:
- network_public
volumes:
- /storage/n8n-redis:/data
command: >
redis-server
--tcp-backlog 8192
--tcp-keepalive 30
--timeout 0
--dir /data
--save 16 1
--save 12 10
--save 6 100
--rdbcompression no
--appendonly yes
--appendfsync everysec
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 5
# ───────────────────────────────────────── N8N Editor
n8n-editor:
<<: *n8n-common
container_name: n8n-editor
hostname: n8n-editor.intranet.br
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-editor
- .env-n8n-web
- .env-n8n-core
- .env-n8n-tasks
volumes:
- /storage/n8n-app/editor:/data
labels:
traefik.enable: "true"
traefik.http.routers.n8n-editor.rule: "Host(`n8n.seudominio.com.br`)"
traefik.http.routers.n8n-editor.entrypoints: "web,websecure"
traefik.http.routers.n8n-editor.tls: "true"
traefik.http.routers.n8n-editor.tls.certresolver: "letsencrypt"
traefik.http.services.n8n-editor.loadbalancer.server.port: "5678"
# ───────────────────────────────────────── N8N Webhook
n8n-webhook:
<<: *n8n-common
container_name: n8n-webhook
hostname: n8n-webhook.intranet.br
command: webhook
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-web
volumes:
- /storage/n8n-app/webhook:/data
labels:
traefik.enable: "true"
traefik.http.routers.n8n-webhook.rule: "Host(`ws.seudominio.com.br`)"
traefik.http.routers.n8n-webhook.entrypoints: "web,websecure"
traefik.http.routers.n8n-webhook.tls: "true"
traefik.http.routers.n8n-webhook.tls.certresolver: "letsencrypt"
traefik.http.services.n8n-webhook.loadbalancer.server.port: "5678"
# ───────────────────────────────────────── N8N Worker
n8n-worker:
<<: *n8n-common
container_name: n8n-worker
hostname: n8n-worker.intranet.br
command: worker
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-core
- .env-n8n-worker
- .env-n8n-tasks
volumes:
- /storage/n8n-app/worker:/data
# ───────────────────────────────────────── N8N Task Runner
n8n-runner:
image: n8nio/runners:2.11.3
container_name: n8n-runner
hostname: n8n-runner.intranet.br
restart: always
cpus: 4
mem_limit: 4g
memswap_limit: 4g
shm_size: 1g
tmpfs:
- /run:rw,noexec,nosuid,size=512m
- /tmp:rw,noexec,nosuid,size=512m
networks:
- network_public
env_file:
- /root/n8n/.env-n8n-global
- /root/n8n/.env-n8n-runner
- /root/n8n/.env-n8n-tasks
volumes:
- /storage/n8n-app/runner:/data
restart: unless-stopped
x
x
x
x
networks:
network_public:
external: true
volumes:
n8n-pgsql-data:
n8n-redis-data:
n8n-editor-data:
n8n-worker-data:
n8n-webhook-data:
n8n-runner-data:
x-n8n-common: &n8n-common
image: docker.n8n.io/n8nio/n8n:2.11.3
restart: always
cpus: 4
mem_limit: 4g
memswap_limit: 4g
shm_size: 1g
tmpfs:
- /run:rw,noexec,nosuid,size=512m
- /tmp:rw,noexec,nosuid,size=512m
networks:
- network_public
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
services:
# ───────────────────────────────────────── PostgreSQL
n8n-pgsql:
image: pgvector/pgvector:pg18-trixie
container_name: n8n-pgsql
hostname: n8n-pgsql.intranet.br
restart: always
read_only: true
cpus: "2.0"
mem_limit: 2g
memswap_limit: 2g
shm_size: 1g
networks:
- network_public
tmpfs:
- /run:rw,noexec,nosuid,size=128m
- /tmp:rw,noexec,nosuid,size=128m
volumes:
- /storage/n8n-pgsql:/var/lib/postgresql/data
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: tulipasql
POSTGRES_DB: n8n
PGDATA: /var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 5s
timeout: 5s
retries: 10
entrypoint: ["docker-entrypoint.sh"]
command:
- postgres
- --max_connections=8192
- --wal_level=minimal
- --max_wal_senders=0
- --port=5432
# ───────────────────────────────────────── Redis
n8n-redis:
image: redis:latest
container_name: n8n-redis
hostname: n8n-redis.intranet.br
restart: always
read_only: true
cpus: "1.0"
mem_limit: 1g
memswap_limit: 1g
working_dir: /data
networks:
- network_public
volumes:
- /storage/n8n-redis:/data
command: >
redis-server
--tcp-backlog 8192
--tcp-keepalive 30
--timeout 0
--dir /data
--save 16 1
--save 12 10
--save 6 100
--rdbcompression no
--appendonly yes
--appendfsync everysec
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 5
# ───────────────────────────────────────── N8N Editor
n8n-editor:
<<: *n8n-common
container_name: n8n-editor
hostname: n8n-editor.intranet.br
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-editor
- .env-n8n-web
- .env-n8n-core
- .env-n8n-tasks
volumes:
- /storage/n8n-app/editor:/data
labels:
traefik.enable: "true"
traefik.http.routers.n8n-editor.rule: "Host(`n8n.seudominio.com.br`)"
traefik.http.routers.n8n-editor.entrypoints: "web,websecure"
traefik.http.routers.n8n-editor.tls: "true"
traefik.http.routers.n8n-editor.tls.certresolver: "letsencrypt"
traefik.http.services.n8n-editor.loadbalancer.server.port: "5678"
# ───────────────────────────────────────── N8N Webhook
n8n-webhook:
<<: *n8n-common
container_name: n8n-webhook
hostname: n8n-webhook.intranet.br
command: webhook
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-web
volumes:
- /storage/n8n-app/webhook:/data
labels:
traefik.enable: "true"
traefik.http.routers.n8n-webhook.rule: "Host(`ws.seudominio.com.br`)"
traefik.http.routers.n8n-webhook.entrypoints: "web,websecure"
traefik.http.routers.n8n-webhook.tls: "true"
traefik.http.routers.n8n-webhook.tls.certresolver: "letsencrypt"
traefik.http.services.n8n-webhook.loadbalancer.server.port: "5678"
# ───────────────────────────────────────── N8N Worker
n8n-worker:
<<: *n8n-common
container_name: n8n-worker
hostname: n8n-worker.intranet.br
command: worker
depends_on:
n8n-pgsql:
condition: service_healthy
n8n-redis:
condition: service_healthy
env_file:
- .env-n8n-global
- .env-n8n-queue
- .env-n8n-redis
- .env-n8n-postgres
- .env-n8n-services
- .env-n8n-core
- .env-n8n-worker
- .env-n8n-tasks
volumes:
- /storage/n8n-app/worker:/data
# ───────────────────────────────────────── N8N Task Runner
n8n-runner:
image: n8nio/runners:2.11.3
container_name: n8n-runner
hostname: n8n-runner.intranet.br
restart: always
cpus: 4
mem_limit: 4g
memswap_limit: 4g
shm_size: 1g
tmpfs:
- /run:rw,noexec,nosuid,size=512m
- /tmp:rw,noexec,nosuid,size=512m
networks:
- network_public
env_file:
- /root/n8n/.env-n8n-global
- /root/n8n/.env-n8n-runner
- /root/n8n/.env-n8n-tasks
volumes:
- /storage/n8n-app/runner:/data
restart: unless-stopped
networks:
network_public:
external: true
Pronto, seu N8N está completo dentro do padrão da versão 2.
.
.
.
.
“Precisa se perder para achar
lugares que não se acham,
se não todos saberiam onde fica.“
Capitão Barbossa – Piratas do Caribe
Terminamos por hoje!
Patrick Brandão, patrickbrandao@gmail.com
