How to install npm modules?
-
Hi @nebulon!
What if we can install custom npm module from this line export NODE_FUNCTION_ALLOW_EXTERNAL=module1,modulel2,moduleN+1
in /app/data/env.shHere the modified Dockerfile I propose:
FROM cloudron/base:4.2.0@sha256:46da2fffb36353ef714f97ae8e962bd2c212ca091108d768ba473078319a47f4 RUN mkdir -p /app/pkg /app/code WORKDIR /app/code RUN apt-get update && \ apt-get -y install graphicsmagick recutils asciidoctor pandoc musl && \ rm -rf /var/cache/apt /var/lib/apt/lists RUN ln -s /usr/lib/x86_64-linux-musl/libc.so /lib/libc.musl-x86_64.so.1 ARG N8N_VERSION=1.25.1 # Add a script to install npm packages from env.sh COPY install_packages_from_env.sh /app/pkg/ RUN chmod +x /app/pkg/install_packages_from_env.sh # n8n. handlebars and jsonata are just helpful modules that user can enable RUN npm install n8n@${N8N_VERSION} && \ npm install handlebars@4.7.7 jsonata@2.0.2 marked@4.3.0 bwip-js@3.3.0 ajv-formats@2.1.1 odoo-xmlrpc@1.0.8 firebase-admin@11.10.1 # install custom npm modules from the env.sh on the NODE_FUNCTION_ALLOW_EXTERNAL RUN /app/pkg/install_packages_from_env.sh /app/data/env.sh RUN rm -rf /app/code/node_modules/n8n/dist/public && ln -s /run/public /app/code/node_modules/n8n/dist/public ENV N8N_USER_FOLDER="/app/data/user" ENV N8N_CONFIG_FILES="/app/data/configs/default.json" ENV N8N_CUSTOM_EXTENSIONS="/app/data/custom-extensions" ENV PATH=/app/code/node_modules/.bin:$PATH COPY start.sh env.sh.template /app/pkg/ CMD [ "/app/pkg/start.sh" ]
And here's an example of what the install_packages_from_env.sh script might look like:
#!/bin/bash # Script to install npm packages from env.sh ENV_FILE=$1 if [ -f "$ENV_FILE" ]; then # Extract the line with NODE_FUNCTION_ALLOW_EXTERNAL and check if it's not commented PACKAGES_LINE=$(grep -E '^export NODE_FUNCTION_ALLOW_EXTERNAL=' $ENV_FILE) if [ ! -z "$PACKAGES_LINE" ]; then # Remove 'export ' prefix PACKAGES=$(echo $PACKAGES_LINE | sed 's/export NODE_FUNCTION_ALLOW_EXTERNAL=//') # Split the packages and install them if not already present IFS=',' read -ra ADDR <<< "$PACKAGES" for package in "${ADDR[@]}"; do if [ ! -d "./node_modules/$package" ]; then echo "Installing $package..." npm install $package else echo "$package is already installed." fi done else echo "No packages to install or line is commented out with #." fi else echo "env.sh file not found" fi
On (re)start of n8n, the npm modules should installed.
What do you think?
-
I am not sure I follow the proposal 100% but the main root cause of not being able to install other node_modules is actually that apps run in a read-only filesystem. So I don't see how such a script would fix this problem, but maybe I miss a point in your proposal.
-
@nebulon my proposal is to install the modules when we build the image from the Dockerfile. I open to any other solution.
The modules installed will be on the read-only filesystem. See the Diff from this source
... # Add a script to install npm packages from env.sh COPY install_packages_from_env.sh /app/pkg/ RUN chmod +x /app/pkg/install_packages_from_env.sh ... # install custom npm modules from the env.sh on the NODE_FUNCTION_ALLOW_EXTERNAL RUN /app/pkg/install_packages_from_env.sh /app/data/env.sh ...
-
Recently, with nodebb we started experimenting with making the node_modules writable (grudgingly). Maybe we can do the same for n8n.
-
This is implemented in https://docs.cloudron.io/apps/n8n/#custom-node-modules .
@shrey let me know if you get a chance to test it.
-