# 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 websocket-client sickle selenium # Copy the launcher config file #COPY docker/runners/n8n-task-runners.json /etc/n8n-task-runners.json COPY ./n8n-task-runners.json /etc/n8n-task-runners.json USER runner