Voltar para blog

n8n no FastPanel: Instalação, Atualização, Rollback e Operação Segura

28/06/2025 · 3 min · Infraestrutura

Compartilhar

Em ambiente de automação, atualizar o n8n não é só trocar a tag da imagem. Quando a instância já tem workflows críticos, filas e credenciais sensíveis, a atualização precisa de janela controlada, backup consistente e validação objetiva. Neste guia, documento o fluxo que uso em produção para atualizar n8n em stack FastPanel com risco controlado.

Contexto operacional e risco real

No meu cenário, a stack era composta por:

A versão em uso estava desatualizada e havia diferença de comportamento entre workflows novos e antigos. O risco principal era:

  1. quebra de compatibilidade em nós após upgrade de versão;
  2. inicialização parcial do n8n-worker enquanto o n8n principal falhava;
  3. perda de tempo de resposta por falta de health checks consistentes.

Pré-check obrigatório antes da mudança

Antes de tocar em docker-compose.yml, eu executo um snapshot do estado atual para ter referência de rollback.

cd /opt/n8n_stack

docker compose ps

docker compose images

docker logs --tail=80 n8n

docker logs --tail=80 n8n-worker

Também valido espaço em disco e status do banco, para evitar falha durante pull da nova imagem:

df -h

docker system df

docker exec -it postgres pg_isready -h localhost -U "$POSTGRES_USER" -d "$POSTGRES_DB"

Backup operacional (estado + dados)

Eu salvo três camadas de backup:

  1. arquivo de composição;
  2. variáveis de ambiente;
  3. dados de runtime do n8n.
cp docker-compose.yml docker-compose.yml.bak.$(date +%F-%H%M)
cp .env .env.bak.$(date +%F-%H%M)

tar -czf /root/backup-n8n-storage-$(date +%F-%H%M).tar.gz /opt/n8n_stack/n8n_storage

Se houver mudança de major version, eu também exporto banco:

docker exec -t postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > /root/backup-n8n-db-$(date +%F-%H%M).sql

Ajuste da imagem com estratégia de versão

Evito latest em produção contínua. Uso latest apenas em laboratório ou homologação. Em produção, prefiro versão fixa para previsibilidade.

Exemplo de troca de imagem:

x-shared: &shared
  restart: always
  image: docker.n8n.io/n8nio/n8n:1.99.1

Se você optar por latest, faça isso com janela curta e monitoramento:

x-shared: &shared
  restart: always
  image: docker.n8n.io/n8nio/n8n:latest

Modelo de stack com health checks consistentes

version: '3.8'

x-shared: &shared
  restart: always
  image: docker.n8n.io/n8nio/n8n:1.99.1
  env_file: .env
  user: "1000:1000"
  volumes:
    - /opt/n8n_stack/n8n_storage:/home/node/.n8n
    - ./healthcheck.js:/healthcheck.js
  depends_on:
    redis:
      condition: service_healthy
    postgres:
      condition: service_healthy

services:
  postgres:
    image: postgres:11
    restart: always
    env_file: .env
    ports:
      - "127.0.0.1:5433:5432"
    volumes:
      - /opt/n8n_stack/db_storage:/var/lib/postgresql/data
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 10s
      timeout: 10s
      retries: 30
      start_period: 60s

  redis:
    image: redis:6-alpine
    restart: always
    volumes:
      - /opt/n8n_stack/redis_storage:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    <<: *shared
    ports:
      - "127.0.0.1:5678:5678"
    healthcheck:
      test: ["CMD", "node", "/healthcheck.js"]
      interval: 10s
      timeout: 10s
      retries: 20
      start_period: 60s

  n8n-worker:
    <<: *shared
    command: worker
    depends_on:
      - n8n
    healthcheck:
      test: ["CMD-SHELL", "node -e 'process.exit(0)'"]
      interval: 30s
      timeout: 5s
      retries: 3

Execução do upgrade

Eu aplico atualização com pull explícito e subida em background.

docker compose pull

docker compose up -d --remove-orphans

Depois valido estado dos containers:

docker compose ps

Validação pós-mudança (checklist real)

  1. conferir versão de imagem em execução:
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'
  1. verificar logs de migração/startup:
docker logs --tail=150 n8n
  1. validar worker processando execução:
docker logs --tail=150 n8n-worker
  1. abrir UI e testar:

Troubleshooting que já enfrentei

Erro de permissão em volume

Sintoma: n8n sobe, mas não persiste credenciais.

Correção:

chown -R 1000:1000 /opt/n8n_stack/n8n_storage
chmod -R 750 /opt/n8n_stack/n8n_storage

Worker em loop de restart

Sintoma: n8n-worker reinicia continuamente.

Validação: dependência de redis ou mismatch de variáveis no .env.

Mudança de versão quebra nó específico

Ação: rollback imediato para tag anterior e abertura de janela de correção em homologação.

Rollback documentado

Se o comportamento pós-upgrade for inconsistente:

cp docker-compose.yml.bak.YYYY-MM-DD-HHMM docker-compose.yml

docker compose up -d

Se necessário, restaurar backup de storage e dump de banco.

Instalação inicial (bootstrap) para novos ambientes

Quando o ambiente ainda não existe, eu sigo este bootstrap mínimo antes do primeiro deploy:

  1. preparar diretório /opt/n8n_stack e volumes (n8n_storage, db_storage, redis_storage);
  2. criar .env com chaves fortes e timezone consistente;
  3. subir stack validando postgres e redis como healthy;
  4. testar login no painel e execução manual de um workflow simples;
  5. documentar versão-base para próximas janelas de upgrade.

Conclusão operacional

Atualização de n8n em FastPanel só é segura quando tratada como mudança de infraestrutura, não como ajuste cosmético. O ganho real vem de três pilares:

Esse modelo reduziu incidentes no meu ambiente e deixou o processo repetível para qualquer janela de manutenção.

CC BY-NC

Este post está licenciado sob CC BY-NC.

Comentários

Participe da discussão abaixo.