MV Melhor VPS

Guia

Como configurar n8n self-hosted em VPS

Instale n8n self-hosted em uma VPS com Docker, PostgreSQL, Nginx, SSL, firewall e backups básicos em 30-40 minutos, com testes e validação segura hoje

Revisão editorial: Concluída
⏱ Tempo estimado: 30-40 minutos
📊 Dificuldade: Intermediário

Tempo estimado: 30-40 minutos

Neste guia você vai instalar o n8n self-hosted em uma VPS Ubuntu 24.04 usando Docker Compose, PostgreSQL, Nginx como proxy reverso e HTTPS com Let’s Encrypt. A ideia é deixar uma base pronta para automações reais, com persistência de dados, firewall ativo e comandos de verificação em cada etapa.

Antes de começar, escolha uma VPS com folga para seus workflows. Para testes, 1 vCPU e 2 GB de RAM funcionam, mas automações com muitos webhooks, chamadas HTTP e processamento de arquivos ficam mais estáveis com 2 vCPU e 4 GB. Se você ainda está dimensionando o ambiente, veja o guia de VPS para n8n e a análise sobre como escolher VPS para n8n. Se o servidor também hospedar APIs, filas ou bancos auxiliares, a página de VPS para desenvolvedores ajuda a pensar em CPU, RAM e armazenamento.

O que você vai aprender

Ao final do guia, você terá uma instalação funcional do n8n acessível por HTTPS no seu domínio. Você também vai entender o que cada componente faz, porque o n8n não deve ficar exposto diretamente na porta do container e como validar se o banco e o proxy estão respondendo.

Você vai aprender a:

  • Preparar uma VPS Ubuntu limpa para hospedar o n8n com segurança básica.
  • Instalar Docker Engine e Docker Compose usando o repositório oficial.
  • Configurar UFW liberando apenas SSH, HTTP e HTTPS.
  • Criar um arquivo .env com credenciais, URL pública e chave de criptografia.
  • Subir PostgreSQL e n8n com volumes persistentes usando docker compose.
  • Configurar Nginx como proxy reverso para encaminhar tráfego ao n8n.
  • Emitir certificado TLS gratuito com Certbot e testar acesso por HTTPS.

O tutorial usa o domínio automacoes.seudominio.com.br nos exemplos. Troque esse valor pelo subdomínio real que você controla. Antes de executar a parte de HTTPS, crie um registro DNS tipo A apontando seu subdomínio para o IP público da VPS. Sem esse apontamento, o Certbot não consegue validar o domínio.

Pré-requisitos

Você precisa de uma VPS com Ubuntu 22.04 ou 24.04, acesso SSH com usuário sudo e um domínio ou subdomínio apontando para o IP do servidor. O guia também funciona em Debian recente com pequenas diferenças de pacotes, mas os comandos foram escritos para Ubuntu. Se você usa outra distribuição, valide os nomes dos pacotes antes de copiar comandos.

No seu computador local, abra o terminal e conecte via SSH. Substitua deploy pelo seu usuário e 203.0.113.10 pelo IP da sua VPS:

ssh [email protected]

A primeira conexão costuma pedir confirmação da chave do host:

The authenticity of host 203.0.113.10 cannot be established.
Are you sure you want to continue connecting? yes

Depois de entrar, confirme o sistema e o usuário atual:

lsb_release -a
whoami
sudo -v

Você deve ver algo parecido com:

Distributor ID: Ubuntu
Description:    Ubuntu 24.04 LTS
Release:        24.04
deploy

Antes de alterar arquivos críticos, crie uma pasta de trabalho e registre o IP público. Isso facilita copiar comandos e manter a configuração organizada:

mkdir -p ~/n8n-stack
cd ~/n8n-stack
curl -4 ifconfig.me && echo

Saída esperada:

203.0.113.10

Se o comando não retornar o IP correto, confira se você está na VPS certa. Parece simples, mas evita configurar automações no servidor errado.

Passo 1: Preparar a VPS e atualizar o sistema

Comece atualizando a lista de pacotes e aplicando correções de segurança. Essa etapa pode reiniciar serviços do sistema, então execute em uma janela de manutenção se a VPS já estiver hospedando algo. Em uma instalação nova, o risco é baixo.

sudo apt update
sudo apt upgrade -y

A saída deve terminar sem erros, com algo próximo de:

Reading package lists... Done
Building dependency tree... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Instale ferramentas que serão usadas nos próximos passos. O ca-certificates permite validar repositórios HTTPS, curl baixa chaves e pacotes, gnupg gerencia assinatura de repositórios, e lsb-release ajuda scripts a identificar a versão do Ubuntu.

sudo apt install -y ca-certificates curl gnupg lsb-release nano openssl

Confirme que os comandos essenciais estão disponíveis:

curl --version | head -n 1
openssl version

Output esperado:

curl 8.5.0
OpenSSL 3.0.13

Agora ajuste o timezone. Isso não é obrigatório para o n8n funcionar, mas deixa logs, execuções agendadas e troubleshooting muito mais claros. Use o fuso que faz sentido para você:

sudo timedatectl set-timezone America/Sao_Paulo
timedatectl

Você deve ver:

Time zone: America/Sao_Paulo
System clock synchronized: yes

Se System clock synchronized aparecer como no, aguarde alguns segundos e rode timedatectl novamente. Workflows com cron dependem de horário consistente, então não pule essa checagem.

Passo 2: Instalar Docker, Compose e configurar firewall

O n8n pode ser instalado com Node.js diretamente no sistema, mas Docker Compose facilita upgrades, rollback e isolamento. Vamos usar o repositório oficial do Docker, não o pacote antigo do Ubuntu. Primeiro, crie o diretório de chaves e adicione a chave GPG oficial:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Adicione o repositório do Docker:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

Instale os pacotes:

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Verifique as versões:

docker --version
docker compose version

Saída esperada:

Docker version 27.5.1, build 9f9e405
Docker Compose version v2.32.4

Adicione seu usuário ao grupo docker para não precisar de sudo em todo comando. Depois, aplique a nova sessão do grupo:

sudo usermod -aG docker $USER
newgrp docker
docker run --rm hello-world

O teste deve mostrar:

Hello from Docker!
This message shows that your installation appears to be working correctly.

Agora configure o firewall. Antes de ativar o UFW, libere SSH para não se bloquear fora da VPS:

sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status numbered

Você verá regras parecidas com:

Status: inactive
[ 1] OpenSSH ALLOW IN Anywhere
[ 2] 80/tcp  ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere

Ative o firewall somente depois de confirmar as regras:

sudo ufw enable
sudo ufw status verbose

Saída esperada:

Status: active
To                         Action      From
OpenSSH                    ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere

Passo 3: Criar variáveis, rede e banco PostgreSQL

Nesta etapa você vai preparar as variáveis usadas pelo n8n e pelo PostgreSQL. A chave N8N_ENCRYPTION_KEY protege credenciais salvas no n8n. Se você perder essa chave, credenciais existentes podem ficar ilegíveis após restaurações. Guarde uma cópia em um gerenciador de senhas.

Entre na pasta do projeto e gere segredos fortes:

cd ~/n8n-stack
openssl rand -hex 32
openssl rand -base64 24

A saída será diferente na sua VPS, por exemplo:

2b0b9b6d8c4c3f1f1f7c5e6a74c99fd8715a3d4a8d2e63f7f6b2f83f5b4d0c17
Q9TjH4mSgVaY7pLk2Nf8xBzA

Crie o arquivo .env. Se ele já existir, faça backup antes. Esse comando não apaga nada, apenas copia o arquivo atual com timestamp:

cd ~/n8n-stack
if [ -f .env ]; then cp .env .env.backup.$(date +%Y%m%d-%H%M%S); fi
nano .env

Cole o conteúdo abaixo e troque automacoes.seudominio.com.br, SENHA_POSTGRES_FORTE_AQUI e CHAVE_HEX_GERADA_AQUI pelos seus valores reais:

DOMAIN_NAME=automacoes.seudominio.com.br
GENERIC_TIMEZONE=America/Sao_Paulo
POSTGRES_USER=n8n
POSTGRES_PASSWORD=SENHA_POSTGRES_FORTE_AQUI
POSTGRES_DB=n8n
N8N_ENCRYPTION_KEY=CHAVE_HEX_GERADA_AQUI
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=SENHA_ADMIN_FORTE_AQUI

Salve no Nano com Ctrl+O, pressione Enter e saia com Ctrl+X. Ajuste permissões para evitar leitura por outros usuários:

chmod 600 .env
ls -l .env

Output esperado:

-rw------- 1 deploy deploy 286 Jun 29 10:15 .env

Crie também uma rede Docker dedicada. Ela permite que Nginx e n8n conversem pelo nome do serviço sem expor portas desnecessárias ao mundo:

docker network create n8n_network
docker network ls | grep n8n_network

Saída esperada:

n8n_network   bridge    local

Se a rede já existir, o Docker mostrará erro informando que ela já foi criada. Nesse caso, siga em frente.

Passo 4: Subir o n8n com Docker Compose

Agora você vai criar o docker-compose.yml. Ele terá dois serviços: postgres, responsável pelo banco, e n8n, responsável pela aplicação. Os dados ficam em volumes Docker nomeados, então reiniciar ou atualizar containers não apaga workflows. Mesmo assim, faça backup antes de upgrades futuros.

Crie o arquivo:

cd ~/n8n-stack
if [ -f docker-compose.yml ]; then cp docker-compose.yml docker-compose.yml.backup.$(date +%Y%m%d-%H%M%S); fi
nano docker-compose.yml

Cole a configuração:

services:
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - n8n_network
    healthcheck:
      test: [CMD-SHELL, pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    container_name: n8n-app
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_HOST: ${DOMAIN_NAME}
      N8N_PORT: 5678
      N8N_PROTOCOL: https
      WEBHOOK_URL: https://${DOMAIN_NAME}/
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${GENERIC_TIMEZONE}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_BASIC_AUTH_ACTIVE: true
      N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER}
      N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
    volumes:
      - n8n_data:/home/node/.n8n
    networks:
      - n8n_network
    ports:
      - 127.0.0.1:5678:5678

volumes:
  postgres_data:
  n8n_data:

networks:
  n8n_network:
    external: true

Valide a sintaxe antes de subir:

docker compose config > /tmp/n8n-compose-check.yml
head -n 5 /tmp/n8n-compose-check.yml

Se estiver correto, você verá o Compose renderizado:

name: n8n-stack
services:
  n8n:
    container_name: n8n-app

Suba os containers em segundo plano:

docker compose up -d

Acompanhe o estado:

docker compose ps

Saída esperada:

NAME           IMAGE                 SERVICE    STATUS
n8n-app        n8nio/n8n:latest      n8n        Up
n8n-postgres   postgres:16-alpine    postgres   Up healthy

Teste localmente na VPS:

curl -I http://127.0.0.1:5678

Você deve receber uma resposta HTTP, normalmente 200, 302 ou 401, dependendo do estado inicial e da autenticação básica.

Passo 5: Configurar Nginx como proxy reverso

O container do n8n está escutando apenas em 127.0.0.1:5678. Isso é intencional. O acesso público será feito pelo Nginx, que recebe HTTP e HTTPS, repassa para o n8n e mantém cabeçalhos corretos para webhooks. Instale o Nginx:

sudo apt install -y nginx
sudo systemctl enable nginx
sudo systemctl status nginx --no-pager

Você deve ver:

Active: active (running)

Antes de criar o site, carregue o domínio do .env na sessão atual:

cd ~/n8n-stack
set -a
. ./.env
set +a
echo $DOMAIN_NAME

Saída esperada:

automacoes.seudominio.com.br

Crie a configuração do Nginx:

sudo nano /etc/nginx/sites-available/n8n

Cole o bloco abaixo, trocando o domínio se você não carregou a variável corretamente:

server {
    listen 80;
    server_name automacoes.seudominio.com.br;

    client_max_body_size 50m;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        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_read_timeout 300s;
        proxy_send_timeout 300s;
    }
}

Ative o site. Se já existir um link antigo, faça backup do arquivo antes de alterar:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/n8n
sudo nginx -t

Output esperado:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Recarregue o Nginx:

sudo systemctl reload nginx

Teste por HTTP usando o cabeçalho Host, útil mesmo antes do DNS propagar:

curl -I -H 'Host: automacoes.seudominio.com.br' http://127.0.0.1

Você deve receber resposta do n8n via Nginx:

HTTP/1.1 200 OK
Server: nginx

Passo 6: Ativar HTTPS com Let’s Encrypt

Com o proxy funcionando em HTTP, emita o certificado TLS. Antes de executar, confirme se o DNS do domínio aponta para a VPS. Rode este comando na própria VPS:

getent hosts automacoes.seudominio.com.br

Saída esperada, com o IP da sua VPS:

203.0.113.10 automacoes.seudominio.com.br

Se aparecer outro IP ou nada for retornado, corrija o DNS e aguarde a propagação. O Certbot precisa acessar sua VPS pela porta 80. Instale Certbot e o plugin do Nginx:

sudo apt install -y certbot python3-certbot-nginx
certbot --version

Output esperado:

certbot 2.9.0

Execute a emissão do certificado. Troque o e-mail por um endereço que você monitora:

sudo certbot --nginx -d automacoes.seudominio.com.br --redirect --agree-tos -m [email protected]

Se tudo der certo, você verá:

Successfully deployed certificate for automacoes.seudominio.com.br to /etc/nginx/sites-enabled/n8n
Congratulations! You have successfully enabled HTTPS

Teste a renovação automática sem alterar certificados reais:

sudo certbot renew --dry-run

Saída esperada:

Congratulations, all simulated renewals succeeded

Agora acesse no navegador:

https://automacoes.seudominio.com.br

Na primeira abertura, o n8n exibirá a tela de criação do usuário inicial ou a autenticação básica, conforme a versão e configuração. Use uma senha forte e guarde as credenciais. Não compartilhe o editor do n8n publicamente com usuários que não precisam criar workflows.

Verificação e testes

Depois da instalação, valide as quatro camadas: containers, banco, proxy e HTTPS. Comece pelos containers:

cd ~/n8n-stack
docker compose ps
docker compose logs --tail=50 n8n

Você deve ver o n8n iniciado sem erro de banco:

n8n ready on 0.0.0.0, port 5678
Editor is now accessible via: https://automacoes.seudominio.com.br

Teste o PostgreSQL por dentro do container:

docker exec n8n-postgres pg_isready -U n8n -d n8n

Saída esperada:

/var/run/postgresql:5432 - accepting connections

Teste o proxy local:

curl -I http://127.0.0.1:5678
curl -I https://automacoes.seudominio.com.br

A segunda resposta deve mostrar HTTPS válido:

HTTP/2 200
server: nginx

Crie um workflow simples no n8n com um gatilho Manual Trigger e um nó Set. Execute o workflow e confirme se ele roda sem erro. Para testar webhooks, crie um workflow com Webhook Trigger em modo test, copie a URL exibida pelo n8n e chame com curl a partir do seu computador:

curl -X POST https://automacoes.seudominio.com.br/webhook-test/ping -H 'Content-Type: application/json' -d '{"status":"ok"}'

Se o workflow estiver ouvindo, o n8n registra a execução na tela. Se retornar 404, confira se o workflow está ativo ou se você usou URL de teste fora do modo de escuta.

Troubleshooting

1. O navegador mostra 502 Bad Gateway. Esse erro normalmente significa que o Nginx não consegue falar com o container do n8n. Verifique se o n8n está de pé:

cd ~/n8n-stack
docker compose ps
curl -I http://127.0.0.1:5678

Se o curl falhar, veja os logs:

docker compose logs --tail=100 n8n

Procure mensagens de senha de banco incorreta, variável ausente ou falha de permissão no volume. Corrija o .env, valide com docker compose config e reinicie com docker compose up -d. Esse reinício não apaga volumes, mas pode interromper execuções em andamento.

2. O Certbot falha com erro de validação. Primeiro confirme DNS e firewall:

getent hosts automacoes.seudominio.com.br
sudo ufw status
curl -I http://automacoes.seudominio.com.br

A porta 80 precisa responder publicamente. Se o domínio aponta para outro IP, ajuste o registro A. Se usa proxy de CDN, desative o proxy temporariamente durante a emissão. Depois rode novamente:

sudo certbot --nginx -d automacoes.seudominio.com.br --redirect --agree-tos -m [email protected]

3. Webhooks geram URL com HTTP ou domínio errado. Isso costuma acontecer quando WEBHOOK_URL, N8N_HOST ou N8N_PROTOCOL estão incorretos no .env. Faça backup antes de editar:

cd ~/n8n-stack
cp .env .env.backup.$(date +%Y%m%d-%H%M%S)
nano .env

Confirme estes valores:

DOMAIN_NAME=automacoes.seudominio.com.br
N8N_ENCRYPTION_KEY=CHAVE_HEX_GERADA_AQUI

Depois reinicie:

docker compose up -d

4. Login ou credenciais aparecem quebrados após restauração. Verifique se a chave N8N_ENCRYPTION_KEY é a mesma do ambiente original. Sem ela, o n8n pode iniciar, mas não consegue descriptografar credenciais salvas. Recupere a chave do backup do .env e reinicie os containers.

Próximos passos

Com o n8n funcionando, configure uma rotina de backup. O mínimo recomendado é copiar o .env, o docker-compose.yml e dumps do PostgreSQL para fora da VPS. Um backup simples pode ser gerado assim:

mkdir -p ~/n8n-backups
docker exec n8n-postgres pg_dump -U n8n n8n > ~/n8n-backups/n8n-$(date +%Y%m%d-%H%M%S).sql
cp ~/n8n-stack/.env ~/n8n-backups/env-$(date +%Y%m%d-%H%M%S).backup
ls -lh ~/n8n-backups

Output esperado:

-rw-r--r-- 1 deploy deploy 1.2M Jun 29 11:10 n8n-20260629-111000.sql
-rw------- 1 deploy deploy 286 Jun 29 11:10 env-20260629-111000.backup

Depois, envie esses arquivos para outro servidor, storage S3 compatível ou repositório privado criptografado. Não deixe seu único backup dentro da mesma VPS.

Também pense em monitoramento. Verifique CPU, RAM, disco e logs do Docker. Workflows com filas grandes ou muitas execuções simultâneas podem exigir Redis e modo queue do n8n, além de workers separados. Para ambientes de produção com muitos webhooks, planeje limites de execução, retenção de dados e alertas de falha. Assim você evita descobrir problemas apenas quando uma automação crítica parar de responder.

Perguntas frequentes

Posso instalar n8n sem Docker na VPS?

Pode, mas Docker Compose costuma ser mais previsível para VPS. Com Docker você isola dependências, mantém PostgreSQL e n8n em serviços separados e simplifica atualizações. Uma instalação direta com Node.js exige controlar versão do Node, processo em segundo plano, logs, permissões e upgrades manualmente. Para ambientes pequenos, Docker também facilita backup dos arquivos de configuração e recriação do serviço em outra VPS. Se você já tem uma stack Node.js bem administrada, a instalação nativa é possível, mas o guia usa Docker por reduzir variações entre servidores.

Quanto de RAM uma VPS precisa para rodar n8n?

Para testes e automações leves, 2 GB de RAM podem ser suficientes, especialmente usando poucos workflows simultâneos. Para uso contínuo, webhooks frequentes, integrações com APIs externas e manipulação de arquivos, prefira 4 GB ou mais. O PostgreSQL, o n8n, o Nginx e o próprio sistema operacional competem por memória. Se a VPS começar a usar swap com frequência, execuções ficam lentas e podem falhar por timeout. Monitore consumo real após colocar seus workflows em produção antes de reduzir recursos.

Por que usar PostgreSQL em vez do SQLite padrão?

O SQLite é prático para testes locais, mas PostgreSQL é mais adequado para VPS e produção. Ele lida melhor com concorrência, volume de execuções, backups consistentes e restaurações. O n8n grava workflows, credenciais e histórico de execução no banco, então a confiabilidade desse componente afeta diretamente suas automações. Com PostgreSQL em container separado, você também consegue fazer dumps com `pg_dump`, restaurar em outra máquina e evoluir para arquiteturas maiores no futuro, como workers e filas.

Preciso deixar a porta 5678 aberta no firewall?

Não. Neste guia, a porta 5678 fica vinculada apenas ao endereço local `127.0.0.1`, então ela não é exposta diretamente na internet. O acesso público passa pelo Nginx nas portas 80 e 443. Esse desenho reduz superfície de ataque e permite usar HTTPS, redirecionamento, limites de upload e cabeçalhos corretos em um ponto central. No UFW, libere apenas SSH, HTTP e HTTPS. Se a porta 5678 aparecer aberta publicamente em uma varredura externa, revise o mapeamento de portas no Compose.

Como atualizar o n8n instalado com Docker Compose?

Antes de atualizar, gere backup do `.env`, do `docker-compose.yml` e do banco PostgreSQL com `pg_dump`. Depois, entre na pasta da stack, rode `docker compose pull` para baixar imagens novas e `docker compose up -d` para recriar os containers. A atualização preserva volumes, mas pode interromper execuções ativas. Leia as notas de versão do n8n antes de upgrades grandes, principalmente quando houver mudanças em credenciais, banco ou variáveis de ambiente. Após atualizar, verifique logs e execute um workflow de teste.

O que fazer se os webhooks do n8n não funcionarem?

Confira primeiro se o workflow está ativo e se você usa a URL correta. URLs com `/webhook-test/` funcionam apenas enquanto o editor está aguardando teste. Para produção, ative o workflow e use a URL com `/webhook/`. Depois verifique `WEBHOOK_URL`, `N8N_HOST` e `N8N_PROTOCOL` no Compose. Se o n8n gerar links com HTTP ou domínio errado, reinicie os containers após corrigir variáveis. Também teste HTTPS com `curl -I` e confirme que o Nginx repassa cabeçalhos `X-Forwarded-Proto` e `Host`.

Fontes consultadas