I’m trying to create a custom Docker image for n8n that includes Python libraries like librosa and numpy so I can use them in my workflows. I’ve been attempting to build a custom image based on n8nio/n8n by installing Python and the libraries, but I keep running into errors during the build process, such as externally-managed-environment and missing compilers for scikit-learn (a dependency of librosa). I’ve tried using pipx and virtual environments, but I’m still facing issues.
I’d like to know the best way to install Python libraries in a custom Docker image for n8n, ensuring they’re accessible to the node user running n8n, so I can call them in an “Execute Command” node and process audio files in my workflow.
Here’s my current Dockerfile:
FROM n8nio/n8n
# Switch to root user to install system packages
USER root
# Install Python, pip, and build dependencies
RUN apk add --no-cache \
python3 \
py3-pip \
curl \
ffmpeg \
build-base \
python3-dev \
g++ \
musl-dev \
libffi-dev \
openssl-dev \
cargo \
pkgconfig \
portaudio-dev
# Create a virtual environment
RUN python3 -m venv /opt/venv
# Update PATH to use the virtual environment's binaries
ENV PATH="/opt/venv/bin:$PATH"
# Install pipx in the virtual environment
RUN pip install --no-cache-dir pipx
RUN pipx ensurepath
# Switch to the node user for Python package installations
USER node
# Install Python packages using pipx as the node user
RUN pipx install speedtest-cli \
&& pipx install librosa \
&& pipx install numpy
# Set Python environment variable
ENV PYTHONUNBUFFERED=1
When I build the image with docker build -t n8n-image . (Yes, my image is set to n8n-image in docker-compose.yml), I get the error during the pipx install step for librosa. I’ve also encountered externally-managed-environment errors in earlier attempts when trying to install packages directly with pip, which is why I switched to using a virtual environment and pipx.
Information on my n8n setup
n8n version: Latest
Running n8n via: Docker
Operating system: My host OS is Ubuntu 22.04, but the container is based on Alpine Linux (from n8nio/n8n)
The core issues stem from Alpine’s musl libc, missing build tools, and pipx enforcing isolation that isn’t ideal in a container. Here’s a cleaner and more reliable solution:
Recommended Dockerfile (No pipx, use system pip in venv)
FROM n8nio/n8n
# Switch to root to install packages
USER root
# Install Python and required build tools
RUN apk add --no-cache \
python3 \
py3-pip \
ffmpeg \
build-base \
python3-dev \
libffi-dev \
openssl-dev \
cargo \
portaudio-dev \
musl-dev \
g++ \
pkgconfig
# Upgrade pip and create venv
RUN python3 -m ensurepip && \
pip3 install --no-cache --upgrade pip setuptools wheel && \
python3 -m venv /opt/venv
# Add venv to path
ENV PATH="/opt/venv/bin:$PATH"
# Install Python packages
RUN pip install --no-cache-dir \
librosa \
numpy \
scikit-learn \
soundfile \
audioread
# Switch back to node user
USER node
Key Points
Avoid pipx for containers; it’s meant for isolated CLI tools.
Install Python directly via pip in a venv (/opt/venv) to keep it clean.
librosa needs scikit-learn, which needs a compiler — handled via build-base and g++.
Set PATH for both build-time and runtime access to the Python environment.
In n8n: Use Execute Command Node
Use commands like:
python3 /data/scripts/audio_analysis.py
Place scripts in a mounted volume (e.g., ./scripts:/data/scripts) and make sure the shebang (#!/opt/venv/bin/python) is set if running as executable.
Let the docker-compose.yml point to image: n8n-image and mount volumes as needed.
This setup avoids permission errors, pipx headaches, and keeps your Python toolchain available to the node user.
Thank you for the detailed answer. I have another question regarding the user setting for n8n. Do you think setting the n8n to run as root is a bad practice? The thing is I have to use a lot of execute command nodes for basic commands that need permissions (e.g. mkdir, rm…). It would be annoying to write a separate script file for each of these basic commands so they could be run even if the n8n user is set to node. What would you advise?
Running n8n as root is technically possible but not recommended unless absolutely necessary. It introduces security risks that can be exploited—especially when you’re using nodes like Execute Command, which can run arbitrary shell code.
That said, here’s a balanced way to approach it:
Why Running as Root Is Risky
Security: Any vulnerability in n8n or your workflow (intentional or not) gives full system access.
Sandbox Bypass: Malicious or malformed workflows could run rm -rf /, start network scans, etc.
User Error: A small typo in an Execute Command node could do major damage.
Recommended Alternatives
1. Add Specific sudo Rights for the node User
Add only the needed commands to /etc/sudoers.d/n8n:
node ALL=(ALL) NOPASSWD: /bin/mkdir, /bin/rm
Then in your Execute Command node, run:
sudo mkdir /some/protected/folder
Much safer than full root.
2. Use a Shell Wrapper Script
Run n8n as node (default).
Mount a directory with helper scripts.
Call short scripts like create-dir.sh, clean-dir.sh, etc., that run with elevated privileges.
3. If You Must Run as Root, Isolate
If root is unavoidable:
Use a dedicated container or VM that’s isolated.
Avoid exposing ports or giving it network access to untrusted endpoints.
TL;DR
Avoid running n8n as root.
Use sudo with tight control.
Use helper scripts if you find yourself repeating privileged commands.