N8N: Compilando do zero

Saudações. Vou te ensinar a compilar o N8N do zero usando o código-fonte do projeto N8N no Github.

Esse tutorial é vital para desenvolvedores que desejam personalizar o sistema, criar recursos adicionais e personalizar opções que são fixas no código.

Personalizar permite que você adicione comandos no container (ffmpeg, pilha ssh completa, ferramentas de rede, bibliotecas, etc…) para expandir o “NODE-EXECUTE” para realizar tarefas infinitas com simples comandos. Você pode incorporar bibliotecas Python ou NodeJS para o “NODE-CODE” e adicionar communities-nodes nativamente.

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian) e programas básicos;
  • Instalar o Docker;
  • Internet durante a compilação (download de imagens e dependências);

1 – Preparativos

Vou abordar como compilar e criar uma imagem OCI (Docker).

Os passos necessários são:

  • Escolher a versão – nesse tutorial, observe a variável N8N_VERSION e a palavra VERSAO com atenção. Consulte as versões disponíveis no link:
  • Baixar código completo – usar o comando git para baixar o projeto. Não consegui compilar usando o ZIP/TAR disponibilizado nas releases, se você conseguiu, me mostre como por favor;
  • Criar um container do nodejs – Para resolver as milhares de dependências e produzir um código javascript pronto para uso é necessário de um ambiente de desenvolvimento nodejs completo, para não inundar o host com pacotes, vamos fazer isso em um container temporário;
  • Compilar – Produzir os arquivos byte-code finais para execução junto com as dependências e binários que formam o sistema N8N;
  • Gerar imagem OCI – Criar uma imagem pronta pra uso, da qual iremos rodar os containers para usar o N8N em teste e em produção;

Baixar código completo

No servidor (HOST), usaremos a pasta /usr/local/src como local de trabalho. Considerando que você já instalou o Docker, vamos instalar no HOST as ferramentas necessárias:

Bash
# Pasta de trabalho:
    mkdir -p /usr/local/src;
    cd /usr/local/src;

# Instalar ferramentas necessárias:
    apt-get -y install curl;
    apt-get -y install wget;
    apt-get -y install git;
    apt-get -y install rsync;

Baixar fontes do N8N, garantir fontes na pasta /usr/local/src/n8n-latest:

Bash
# Baixar codigo-fonte do N8N
    N8N_VERSION="1.112.5";
    N8N_SRCDIR="/usr/local/src/n8n-n8n-$N8N_VERSION";

# Clonar repositorio de fontes (download via GIT)
    mkdir -p "$N8N_SRCDIR";
    cd "$N8N_SRCDIR";
    git clone \
        --branch release/$N8N_VERSION \
        --single-branch https://github.com/n8n-io/n8n.git . ;

    # Ajuste de propriedade:
    chown -R 1000:1000 $N8N_SRCDIR;

# Preservar fontes - manter intocado, copiar para pasta de trabalho:
    # - apagar pasta de trabalho anterior, se existir
    cd /usr/local/src;
    rm -rf /usr/local/src/n8n-latest 2>/dev/null;
    mkdir -p /usr/local/src/n8n-latest;
    # - copiar fontes:
    rsync -ravp $N8N_SRCDIR/  /usr/local/src/n8n-latest/;

# Entrar na pasta de fontes para trabalho:
    cd /usr/local/src/n8n-latest;

Esse é o ponto de personalização antes das compilações. Se quiser adicionar algo, esse é o ponto!

2 – Compilando projeto N8N

Para compilar precisamos:

  • Container de NodeJS da versão usada pelo N8N – O projeto possui uma imagem pronta para isso chamada n8nio/base:22 (ou superior a 22);
  • Mapear nesse container a pasta de fontes para que seja produzida a pasta ./compiled/ onde estará todo o projeto pronto para empacotamento e execução;

Container NodeJS para compilação

Bash
# Entrar na pasta de fontes:
    cd /usr/local/src/n8n-latest;

# Obter versao do NodeJS usado pelo N8N
    V=$(egrep 'ARG.NODE_VER' docker/images/n8n-base/Dockerfile | cut -f2 -d=);
    export NODE_VERSION=$V;
    export IMAGE="n8nio/base:${NODE_VERSION}";

# Remover container atual, caso seja a segunda vez que voce tenta!
    docker rm -f n8nio-base 2>/dev/null;

# Garantir versao atualizada da imagem base;
    docker pull $IMAGE;

# Rodar container:
    docker run \
        --rm -d \
        --name n8nio-base \
        --user=root --cap-add=ALL --privileged \
        --shm-size=4g --tmpfs /run:rw,exec,size=4g \
        \
        -v /var/run/docker.sock:/var/run/docker.sock:ro \
        -v /usr/local/src/n8n-latest:/app \
        -w /app \
        $IMAGE sleep 86400;

Iniciar compilação

Bash
# Entrar na pasta de fontes:
    cd /usr/local/src/n8n-latest;

# Rodar comandos de preparacao no container:
    # - Funcao para economizar comando
    _root_run(){ docker exec -it --user root n8nio-base ash -c "$1"; };
    _user_run(){ docker exec -it --user node n8nio-base ash -c "$1"; };

    # Instalar pacotes (opcional)
    _root_run 'apk update; apk upgrade; apk add bash curl wget git strace;';

    # Preparacao: rodar como ROOT
    _root_run 'cd /app; chown node:node /app -R;';
    _root_run 'cd /app; corepack enable;';
    _root_run "cd /app; corepack prepare pnpm@10.12.1 --activate;";
    _root_run 'cd /app; chown node:node /app -R;';
    _root_run 'cd /app; chmod -R u+rwX /app;';

    # Compilar n8n - rodar como usuario comum - vai demorar MUITO
    _user_run "cd /app; corepack prepare pnpm@10.12.1 --activate;";
    _user_run 'cd /app; pnpm --loglevel verbose install;'
    _user_run 'cd /app; pnpm --loglevel verbose build';

    # Unificar pacote - gerar ./compiled/
    _user_run 'cd /app; pnpm --loglevel verbose build:deploy';

    # Opcional - gerar backup da pasta 'compiled'
    echo "# Compactando app compilado";
    (
        cd /usr/local/src/n8n-latest/;
        echo "Empacotando ./compiled, aguarde...";
        tar -cpzf ../n8n-${N8N_VERSION}-compiled.tgz compiled;
    );

Até aqui temos o APP n8n pronto na pasta: /usr/local/src/n8n-latest/compiled

Vamos criar uma imagem Docker para o N8N. Cuidado para não confundir as tags:

  • Tag local: n8n:VERSAO – só existe no nosso servidor;
  • Tag da imagem pública no Docker Hub: n8nio/n8n:VERSAO

Se você precisar adicionar mais programas, binários, bibliotecas, communities-nodes, esse é o momento!

Criar imagem final:

Bash
# Entrar na pasta de fontes:
    cd /usr/local/src/n8n-latest;

# Remover imagem com a tag atual
    docker rmi n8n:$N8N_VERSION 2>/dev/null;
    docker rmi n8n:latest       2>/dev/null;

# Entrar na pasta de fontes:
# - precisa existir a pasta ./compiled/ que criamos no passo anterior
    docker build \
        -f docker/images/n8n/Dockerfile . \
        -t n8n:$N8N_VERSION \
        -t n8n:latest;

# Listar imagens criadas:
docker image ls --filter "reference=n8n";
    # REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
    # n8n          1.112.5   ec4f8c8bba51   2 minutes ago   976MB
    # n8n          latest    ec4f8c8bba51   2 minutes ago   976MB

Imagem pronta.

Você pode fazer push para sua conta no Docker Hub, caso possua uma.

Caso deseje exportar a imagem para um arquivo (backup, jogar no FTP, pendrive, etc…):

Bash
# Salva imagem em um arquivo TAR:
docker save n8n:$N8N_VERSION > /usr/local/src/n8n:$N8N_VERSION.tar;

Se desejar carregar a imagem em outro servidor usando o arquivo TAR gerado acima:

Bash
# No servidor destino, baixe o arquivo TAR, importe usando:
docker load --input=n8n:$N8N_VERSION.tar;

3 – Testando nosso N8N

Vamos rodar um container usando a imagem “n8n:VERSAO” gerada no capítulo 2. Esse container é apenas de teste (modo simples usando SQLITE, totalmente inadequado para producão):

Bash
# Renovar/rodar:
    # Parar container atual:
    docker rm -f n8n-test 2>/dev/null;

    # Criar e rodar:
    docker run -d --restart=always \
        --name n8n-test -h n8n-test.intranet.br \
        --memory=1g --memory-swap=1g \
        -e TZ=America/Sao_Paulo \
        -e GENERIC_TIMEZONE==America/Sao_Paulo \
        -e N8N_HOST=test.site.br \
        -e N8N_PORT=5678 \
        -e N8N_PROTOCOL=http \
        -e NODE_ENV=production \
        -e WEBHOOK_URL=https://n8n-test.site.br/ \
        -e GENERIC_TIMEZONE=America/Sao_Paulo \
        -e SSL_EMAIL=America/Sao_Paulo \
        -e N8N_SECURE_COOKIE=false \
        \
        -p 15678:5678 \
        n8n:$N8N_VERSION;

# Acesso no ip do servidor na porta HTTP 15678

Em caso de problemas, sugestões, recursos adicionais interessantes, me informe.

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com