`N8N_RUNNERS_STDLIB_ALLOW` is not working in docker compose file

Describe the problem/error/question

I have two following docker compose files:

# n8n Queue Mode Deployment
# Base configuration for n8n with separate main instance and worker
# Modified from n8n official docker-compose examples
# Changes:
# 1. Explicit naming for containers, networks, volumes
# 2. Queue mode with Redis broker and dedicated worker
# 3. Postgres 18 for database backend
# 4. Environment configuration in single .env file
# 5. Restart policy: unless-stopped

# Shared environment variables for n8n instances
x-n8n-env: &n8n-env
  # Database configuration
  DB_TYPE: ${DB_TYPE}
  DB_POSTGRESDB_HOST: ${DB_POSTGRESDB_HOST}
  DB_POSTGRESDB_PORT: ${DB_POSTGRESDB_PORT}
  DB_POSTGRESDB_DATABASE: ${DB_POSTGRESDB_DATABASE}
  DB_POSTGRESDB_USER: ${DB_POSTGRESDB_USER}
  DB_POSTGRESDB_PASSWORD: ${DB_POSTGRESDB_PASSWORD}
  # Queue/Redis configuration
  EXECUTIONS_MODE: ${EXECUTIONS_MODE}
  QUEUE_BULL_REDIS_HOST: ${QUEUE_BULL_REDIS_HOST}
  QUEUE_BULL_REDIS_PORT: ${QUEUE_BULL_REDIS_PORT}
  QUEUE_BULL_REDIS_PASSWORD: ${QUEUE_BULL_REDIS_PASSWORD}
  QUEUE_BULL_REDIS_DB: ${QUEUE_BULL_REDIS_DB}
  QUEUE_HEALTH_CHECK_ACTIVE: ${QUEUE_HEALTH_CHECK_ACTIVE}
  OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS: ${OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS}
  # Task runners configuration
  N8N_RUNNERS_ENABLED: ${N8N_RUNNERS_ENABLED}
  N8N_RUNNERS_MODE: ${N8N_RUNNERS_MODE}
  N8N_RUNNERS_BROKER_LISTEN_ADDRESS: ${N8N_RUNNERS_BROKER_LISTEN_ADDRESS}
  N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
  N8N_NATIVE_PYTHON_RUNNER: ${N8N_NATIVE_PYTHON_RUNNER}
  # Timezone
  GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
  TZ: ${TZ}
  # Telemetry
  N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED}
  N8N_PERSONALIZATION_ENABLED: ${N8N_PERSONALIZATION_ENABLED}
  # Execution settings
  EXECUTIONS_DATA_PRUNE: ${EXECUTIONS_DATA_PRUNE}
  EXECUTIONS_DATA_MAX_AGE: ${EXECUTIONS_DATA_MAX_AGE}
  # Security keys
  N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
  N8N_USER_MANAGEMENT_JWT_SECRET: ${N8N_USER_MANAGEMENT_JWT_SECRET}

services:
  # Main n8n instance - handles UI and API
  n8n-main:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
    container_name: n8n-main
    restart: unless-stopped
    environment:
      <<: *n8n-env
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - n8n-data:/home/node/.n8n
    networks:
      - default
    labels: # it's still needed
      - "com.centurylinklabs.watchtower.enable=false"

  # Dedicated worker for executing workflows
  n8n-worker:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
    container_name: n8n-worker
    restart: unless-stopped
    command: worker --concurrency=5
    environment:
      <<: *n8n-env
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - n8n-data:/home/node/.n8n
    networks:
      - default
    labels:
      - "com.centurylinklabs.watchtower.enable=false"

  # Task runner for executing Code nodes (paired with worker)
  n8n-runner:
    # for some reason n8n runners image is not in docker.n8n.io registry
    image: n8nio/runners:${N8N_VERSION}
    container_name: n8n-runner
    restart: unless-stopped
    environment:
      # Connect to worker's Task Broker since executions run on worker in queue mode
      N8N_RUNNERS_TASK_BROKER_URI: ${N8N_RUNNERS_TASK_BROKER_URI}
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT: ${N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT}
      # these two allow built-in modules env vars are not working, workaround via bind-mount
      NODE_FUNCTION_ALLOW_BUILTIN: ${NODE_FUNCTION_ALLOW_BUILTIN}
      N8N_RUNNERS_STDLIB_ALLOW: ${N8N_RUNNERS_STDLIB_ALLOW}
    depends_on:
      - n8n-worker
    networks:
      - default
    labels:
      - "com.centurylinklabs.watchtower.enable=false"

  # PostgreSQL database for n8n
  postgres:
    image: postgres:18-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres-data:/var/lib/postgresql
    networks:
      - default
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 3s
      timeout: 5s
      retries: 5

  # Redis for queue management
  redis:
    image: redis:7-alpine
    container_name: n8n-redis
    restart: unless-stopped
    environment:
      QUEUE_BULL_REDIS_PASSWORD: ${QUEUE_BULL_REDIS_PASSWORD}
    command: sh -c 'redis-server $${QUEUE_BULL_REDIS_PASSWORD:+--requirepass $$QUEUE_BULL_REDIS_PASSWORD}'
    volumes:
      - redis-data:/data
    networks:
      - default
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 3s
      timeout: 3s
      retries: 3

networks:
  default:
    name: n8n-defnet

volumes:
  n8n-data:
    name: n8n-data
  postgres-data:
    name: n8n-postgres-data
  redis-data:
    name: n8n-redis-data

Local Testing Specific Override:

services:
  n8n-main:
    environment:
      # Local development URLs and protocol
      N8N_HOST: localhost
      N8N_PORT: 5678
      N8N_PROTOCOL: http
      WEBHOOK_URL: http://localhost:5678
      N8N_SECURE_COOKIE: false
    ports:
      - "5678:5678"

  n8n-worker:
    environment:
      # Local development URLs and protocol
      N8N_HOST: localhost
      N8N_PORT: 5678
      N8N_PROTOCOL: http
      WEBHOOK_URL: http://localhost:5678

I run both docker compose file together with:

docker compose -f compose.base.yml -f compose.local.yml up -d

And then simply setup a new workflow with JavaScript and Python (Native) (Beta) node (see sample workflow below),

Then observed that the Python node failed with:

Line 2: Import of standard library module 'datetime' is disallowed. Allowed stdlib modules: none

What is the error message (if any)?

See above

Please share your workflow

Share the output returned by the last node

Same as the error message above

Information on your n8n setup

  • n8n version: 1.115.3
  • Database (default: SQLite): Postgres
  • n8n EXECUTIONS_PROCESS setting (default: own, main): queue
  • Running n8n via (Docker, npm, n8n cloud, desktop app): Docker
  • Operating system: WSL2 Debian on Win 10 Pro

More Context

The current workaround works is make a copy of /etc/n8n-task-runners.json file from the n8nio/runners image and manually edit the env var N8N_RUNNERS_STDLIB_ALLOW. Then mount the modified json config file back to the runner container, like following:

  n8n-runner:
    # for some reason n8n runners image is not in docker.n8n.io registry
    image: n8nio/runners:${N8N_VERSION}
    container_name: n8n-runner
    # rest of config
    volumes:
      - ./my-custom-n8n-task-runners.json:/etc/n8n-task-runners.json:ro # with `N8N_RUNNERS_STDLIB_ALLOW=*`

Then it works, basically, the N8N_RUNNERS_STDLIB_ALLOW in the compose file never worked

Let me also share my .env file:

# n8n Environment Configuration
# Copy this file to .env and update the values

# ============================================================================
# Version Configuration
# ============================================================================

# n8n version (must match for both main, worker, runners n8n images)
# check version at https://docs.n8n.io/release-notes/
# n8n runner doesn't have latest tag, and it must match main/worker version
N8N_VERSION=1.115.3

# ============================================================================
# PostgreSQL Configuration
# ============================================================================

# PostgreSQL container settings
POSTGRES_USER=n8n
POSTGRES_PASSWORD=CHANGE_ME_TO_SECURE_PASSWORD
POSTGRES_DB=n8n

# n8n database connection settings (reference values above)
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
DB_POSTGRESDB_USER=${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}

# ============================================================================
# Redis Configuration
# ============================================================================

# Redis password (leave empty for no password, but not recommended)
REDIS_PASSWORD=CHANGE_ME_TO_SECURE_PASSWORD

# n8n queue configuration (reference values above)
QUEUE_BULL_REDIS_HOST=redis
QUEUE_BULL_REDIS_PORT=6379
QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
QUEUE_BULL_REDIS_DB=0

# ============================================================================
# n8n Application Settings
# ============================================================================

# Queue mode settings
EXECUTIONS_MODE=queue
QUEUE_HEALTH_CHECK_ACTIVE=true
OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true

# Task runners (external execution environment for Code nodes)
N8N_RUNNERS_ENABLED=true
N8N_RUNNERS_MODE=external
N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
N8N_RUNNERS_TASK_BROKER_URI=http://n8n-worker:5679
N8N_RUNNERS_AUTH_TOKEN="CHANGE_ME_GENERATE_WITH_openssl_rand_base64_32" # Generate with: openssl rand -base64 32
N8N_RUNNERS_AUTO_SHUTDOWN_TIMEOUT=15
N8N_NATIVE_PYTHON_RUNNER=true
NODE_FUNCTION_ALLOW_BUILTIN=*
N8N_RUNNERS_STDLIB_ALLOW=*

# Timezone and locale
GENERIC_TIMEZONE=America/New_York
TZ=America/New_York

# Telemetry settings
N8N_DIAGNOSTICS_ENABLED=false
N8N_PERSONALIZATION_ENABLED=false

# Execution data management
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168

# ============================================================================
# n8n Security Keys
# IMPORTANT: Generate strong random keys for production!
# ============================================================================

# Encryption key for credentials stored in database
# Generate with: openssl rand -base64 32
N8N_ENCRYPTION_KEY="CHANGE_ME_GENERATE_WITH_openssl_rand_base64_32"

# JWT secret for user management tokens
# Generate with: openssl rand -base64 32
N8N_USER_MANAGEMENT_JWT_SECRET="CHANGE_ME_GENERATE_WITH_openssl_rand_base64_32"

As you can see that I already have N8N_RUNNERS_STDLIB_ALLOW=* set in the task runner container, but that env var is not working

Hi @CXwudi

What about the extras.txt file?

I’m confused too, the docs aren’t very clear about custom images imo :confused:

Hi @mohamed3nan

My understandingextra.txt is only used during build time, because it is only used in Dockerfile

That Dockerfile was the main issue,
I ended up creating my own Dockerfile based on the same runner version, but I replaced extras.txt and n8n-task-runners.json with my settings, and it worked…
However, I believe this should all be handled with environment variables idk..

1 Like