Hi @Wouter_Nigrini @tamy.santos Thanks for responding
this was the Dockerfile I was using for runner
# Stage 1: Install Chromium and dependencies in a full Alpine image
FROM alpine:3.22 AS chromium-installer
RUN apk add --no-cache \
chromium \
nss \
freetype \
freetype-dev \
harfbuzz \
ca-certificates \
ttf-freefont \
font-noto-emoji \
wqy-zenhei
# Stage 2: Copy Chromium and dependencies to the n8n runners image
FROM n8nio/runners:latest
USER root
# Copy Chromium binary, libraries, and fonts from the installer stage
COPY --from=chromium-installer /usr/bin/chromium /usr/bin/chromium
COPY --from=chromium-installer /usr/lib/chromium/ /usr/lib/chromium/
COPY --from=chromium-installer /usr/lib/libnss*.so* /usr/lib/
COPY --from=chromium-installer /usr/lib/libfreetype*.so* /usr/lib/
COPY --from=chromium-installer /usr/lib/libharfbuzz*.so* /usr/lib/
COPY --from=chromium-installer /usr/share/fonts/ /usr/share/fonts/
COPY --from=chromium-installer /etc/fonts/ /etc/fonts/
# Install JavaScript packages for utilities and scraping
RUN cd /opt/runners/task-runner-javascript && \
pnpm add moment uuid lodash dotenv axios got node-fetch puppeteer playwright cheerio jsdom xml2js jsonpath yaml form-data
# Configure Playwright to use system Chromium instead of downloading browsers
# This is necessary because Playwright's bundled browsers don't work well with Alpine's musl libc
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium
# Install Python packages for utilities and scraping
RUN cd /opt/runners/task-runner-python && \
uv pip install requests httpx aiohttp beautifulsoup4 lxml lxml[html_clean] selenium scrapy requests-html mechanize pyquery html5lib cssselect parsel pandas numpy jsonpath-ng pyyaml toml python-dotenv environs python-dateutil arrow pytz pendulum validators email-validator phonenumbers iso8601
# Copy the launcher config file
COPY docker/runners/n8n-task-runners.json /etc/n8n-task-runners.json
USER runner
and this is the custom json file
{
"task-runners": [
{
"runner-type": "javascript",
"workdir": "/home/runner",
"command": "/usr/local/bin/node",
"args": [
"--disallow-code-generation-from-strings",
"--disable-proto=delete",
"/opt/runners/task-runner-javascript/dist/start.js"
],
"health-check-server-port": "5681",
"allowed-env": [
"PATH",
"GENERIC_TIMEZONE",
"NODE_OPTIONS",
"N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT",
"N8N_RUNNERS_TASK_TIMEOUT",
"N8N_RUNNERS_MAX_CONCURRENCY",
"N8N_SENTRY_DSN",
"N8N_VERSION",
"ENVIRONMENT",
"DEPLOYMENT_NAME"
],
"env-overrides": {
"NODE_FUNCTION_ALLOW_BUILTIN": "*",
"NODE_FUNCTION_ALLOW_EXTERNAL": "moment,uuid,lodash,dotenv,axios,got,node-fetch,puppeteer,playwright,cheerio,jsdom,xml2js,jsonpath,yaml,form-data",
"N8N_RUNNERS_HEALTH_CHECK_SERVER_HOST": "0.0.0.0"
}
},
{
"runner-type": "python",
"workdir": "/home/runner",
"command": "/opt/runners/task-runner-python/.venv/bin/python",
"args": [
"-m",
"src.main"
],
"health-check-server-port": "5682",
"allowed-env": [
"PATH",
"N8N_RUNNERS_LAUNCHER_LOG_LEVEL",
"N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT",
"N8N_RUNNERS_TASK_TIMEOUT",
"N8N_RUNNERS_MAX_CONCURRENCY",
"N8N_SENTRY_DSN",
"N8N_VERSION",
"ENVIRONMENT",
"DEPLOYMENT_NAME"
],
"env-overrides": {
"PYTHONPATH": "/opt/runners/task-runner-python",
"N8N_RUNNERS_STDLIB_ALLOW": "*",
"N8N_RUNNERS_EXTERNAL_ALLOW": "requests,httpx,aiohttp,beautifulsoup4,bs4,lxml,selenium,scrapy,requests-html,mechanize,pyquery,html5lib,cssselect,parsel,pandas,numpy,jsonpath-ng,pyyaml,toml,dotenv,environs,python-dateutil,arrow,pytz,pendulum,validators,email-validator,phonenumbers,iso8601"
}
}
]
}