n8n-io / n8n

Free and source-available fair-code licensed workflow automation tool. Easily automate tasks across different services.
https://n8n.io
Other
48.31k stars 7.49k forks source link

Code node: can't use installed node.js packages/modules #7381

Closed pablorq closed 1 year ago

pablorq commented 1 year ago

Describe the bug A package/module installed using npm in the /home/node/.n8n/nodes/ user directory can't be used inside a Code node.

To Reproduce Steps to reproduce the behavior:

  1. Setup n8n docker container
  2. Start container
  3. Run npm install --prefix=/home/node/.n8n/nodes/ @mozilla/readability command
  4. Use the package inside a Code node.
  5. Receive ERROR: Cannot find module ...

Expected behavior Be able to use any installed Node.js package inside a Code node.

Environment (please complete the following information):

Additional context Docker compose file (portainer version):

# Based on https://raw.githubusercontent.com/n8n-io/n8n/master/docker/compose/withPostgres/docker-compose.yml

version: '3.8'

volumes:
  db_data:

services:
  postgres:
    image: postgres:11
    restart: always
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_NON_ROOT_USER=${POSTGRES_NON_ROOT_USER}
      - POSTGRES_NON_ROOT_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data
      - ${N8N_LOCAL_FILES}/n8n-config/init-data.sh:/docker-entrypoint-initdb.d/init-data.sh

  main:
    image: docker.n8n.io/n8nio/n8n:1.8.2
    restart: always
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
      - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
      - GENERIC_TIMEZONE=Europe/Madrid
      - TZ=Europe/Madrid
    ports:
      - 5678:5678
    links:
      - postgres
    depends_on:
      - postgres

# environment
# POSTGRES_USER=postgresuser
# POSTGRES_PASSWORD=mysecretpassword
# POSTGRES_DB=n8n
# POSTGRES_NON_ROOT_USER=postgresnonrootuser
# POSTGRES_NON_ROOT_PASSWORD=mysecretpassword
# N8N_LOCAL_FILES=/home/user/n8n-local-files [ EDIT THIS!!! ]
# N8N_VERSION=1.3.1

Content of ${N8N_LOCAL_FILES}/n8n-config/init-data.sh to initialize n8n database:

#!/bin/bash
set -e;

if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
    psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
        CREATE USER ${POSTGRES_NON_ROOT_USER} WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
        GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_NON_ROOT_USER};
    EOSQL
else
    echo "SETUP INFO: No Environment variables given!"
fi

Output from container's console:

~ $ whoami
node

~ $ npm install --prefix=/home/node/.n8n/nodes/ @mozilla/readability
[..................] | idealTree:nodes: sill idealTree buildDeps

added 1 package in 4s

~ $ 

Create a simple workflow with a Code node with the following:

var test = require('@mozilla/readability');

// Loop over input items and add a new field called 'myNewField' to the JSON of each one
for (const item of $input.all()) {
  item.json.myNewField = 1;
}

return $input.all();

Complete error shown in n8n:

ERROR: Cannot find module '@mozilla/readability' [line 1]
VMError
Details
Stack

VMError: Cannot find module '@mozilla/readability'
    at Resolver.resolveFull (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/resolver.js:126:9)
    at Resolver.resolve (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/resolver.js:121:15)
    at resolve (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/nodevm.js:317:21)
    at VM2 Wrapper.apply (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/bridge.js:485:11)
    at requireImpl (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/setup-node-sandbox.js:90:19)
    at require (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/setup-node-sandbox.js:171:10)
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/Code:1:109
    at /usr/local/lib/node_modules/n8n/node_modules/n8n-nodes-base/dist/nodes/Code:10:2
    at VM2 Wrapper.apply (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/bridge.js:485:11)
    at NodeVM.run (/usr/local/lib/node_modules/n8n/node_modules/@n8n/vm2/lib/nodevm.js:497:23)

Also checked on: https://community.n8n.io/t/install-npm-package/3080/2 https://docs.n8n.io/hosting/installation/npm/#windows-troubleshooting https://community.n8n.io/t/installing-additional-module-with-npm/11682/8 https://community.n8n.io/t/can-i-install-npm-packages/18434/2 https://community.n8n.io/t/can-i-install-npm-packages/18434/2 https://blog.elest.io/how-to-install-additional-libraries-for-n8n/ https://docs.n8n.io/integrations/community-nodes/installation/manual-install/

Joffcom commented 1 year ago

Hey @pablorq,

The recommended way to add a package would be to use a custom image, To do this you can follow the example below.

FROM n8nio/n8n:latest

USER root
RUN npm install -g @mozilla/readability
USER node

The other option would be to run the below

docker exec -u root -it n8n /bin/sh
npm install -g @mozilla/readability

I have done a quick test and both of these options work using your example code snippet

image

The /home/node/.n8n/nodes/ path is only used to load custom nodes not any npm package you want to use in the code node.

pablorq commented 1 year ago

Tried with this:

/home/node # whoami
root

/home/node # npm install -g @mozilla/readability

added 1 package in 2s

/home/node # cd /usr/local/lib/node_modules/

/usr/local/lib/node_modules # ls -hal
total 32K    
drwxr-sr-x    1 root     root        4.0K Oct  9 11:30 .
drwxr-sr-x    1 root     root        4.0K Aug 10 19:24 ..
drwxr-sr-x    3 root     root        4.0K Oct  9 11:30 @mozilla
drwxr-sr-x    4 root     root        4.0K Aug 10 19:24 corepack
drwxr-sr-x    4 root     root        4.0K Aug 31 14:08 full-icu
drwxr-sr-x    6 root     root        4.0K Sep 25 12:14 n8n
drwxr-sr-x    1 root     root        4.0K Aug 31 14:08 npm

/usr/local/lib/node_modules # 

It is installed, but still the same error: Screenshot 2023-10-09 at 11-33-57 n8n - ⚠️ My workflow

Any idea?

netroy commented 1 year ago

Every additional node_module needs to be explicitly added to an allow list. can you try setting the env variable NODE_FUNCTION_ALLOW_EXTERNAL=@mozilla/readability.

pablorq commented 1 year ago

Ouch!

I've deleted it in some test. In fact I'm using `- NODE_FUNCTION_ALLOW_EXTERNAL=* in the docker compose file.

The npm install -g [package-name] did the trick.

Now it works. Thank you!