Skip to content

Running FuncNodes with Docker

FuncNodes publishes Docker images to GitHub Container Registry:

ghcr.io/linkdlab/funcnodes

Use Docker when you want to run FuncNodes without installing Python packages on the host. The image supports two runtime modes:

  • Manager mode: starts the web UI and uses a Workermanager. This is the default.
  • Single-worker mode: starts one persistent worker and a web UI connected directly to it, without a Workermanager.

Pull the Image

Use latest for the newest release:

docker pull ghcr.io/linkdlab/funcnodes:latest

Use a version tag for reproducible deployments:

docker pull ghcr.io/linkdlab/funcnodes:v1.6.0

Run with Docker

Create a local configuration directory first. This keeps workers, settings, and runtime state outside the container:

mkdir -p funcnodes_config

Start FuncNodes:

docker run --rm \
  -p 8000:8000 \
  -p 9380:9380 \
  -p 9382-9482:9382-9482 \
  -e FUNCNODES_RUNSERVER_HOST=0.0.0.0 \
  -e FUNCNODES_RUNSERVER_PORT=8000 \
  -e FUNCNODES_WORKER_MANAGER_HOST=0.0.0.0 \
  -e FUNCNODES_WORKER_MANAGER_PORT=9380 \
  -e FUNCNODES_HOST=0.0.0.0 \
  -e FUNCNODES_WS_WORKER_STARTPORT=9382 \
  -e FUNCNODES_UPDATE_PACKAGES="" \
  -v ./funcnodes_config:/usr/local/app/.funcnodes \
  ghcr.io/linkdlab/funcnodes:latest

Open the UI at:

http://localhost:8000

The worker manager listens on port 9380. Worker websocket ports use the exposed range 9382-9482.

Single-Worker Mode

Use single-worker mode when you want one empty worker and the web frontend without a Workermanager:

docker run --rm \
  -p 8000:8000 \
  -p 9382:9382 \
  -e FUNCNODES_DOCKER_MODE=single-worker \
  -e FUNCNODES_RUNSERVER_HOST=0.0.0.0 \
  -e FUNCNODES_RUNSERVER_PORT=8000 \
  -e FUNCNODES_SINGLE_WORKER_HOST=0.0.0.0 \
  -e FUNCNODES_SINGLE_WORKER_PORT=9382 \
  -v ./funcnodes_config:/usr/local/app/.funcnodes \
  ghcr.io/linkdlab/funcnodes:latest

The container creates the worker once and reuses it on later starts through the mounted funcnodes_config volume. Startup uses funcnodes runserver --no-manager --worker-uuid ...: if the worker is already running, the frontend attaches to its existing port; otherwise the server starts it on FUNCNODES_SINGLE_WORKER_PORT and stops it again when the server exits.

Optional single-worker settings:

Environment variable Default Description
FUNCNODES_SINGLE_WORKER_UUID 00000000000000000000000000000001 Stable worker id used for the persisted worker config.
FUNCNODES_SINGLE_WORKER_NAME docker-single-worker Display name for the worker.
FUNCNODES_SINGLE_WORKER_HOST 0.0.0.0 Bind host inside the container.
FUNCNODES_SINGLE_WORKER_PORT 9382 Worker websocket port.
FUNCNODES_SINGLE_WORKER_PUBLIC_HOST empty Browser-facing worker host for reverse proxies or remote deployments.

For local Docker use, leave FUNCNODES_SINGLE_WORKER_PUBLIC_HOST empty. Set it only when the browser must connect to a public hostname that differs from the HTTP request host.

Run with Docker Compose

Use this docker-compose.yaml:

services:
  funcnodes:
    image: ghcr.io/linkdlab/funcnodes:latest
    ports:
      - "8000:8000"
      - "9380:9380"
      - "9382-9482:9382-9482"
    environment:
      FUNCNODES_RUNSERVER_HOST: "0.0.0.0"
      FUNCNODES_RUNSERVER_PORT: "8000"
      FUNCNODES_WORKER_MANAGER_HOST: "0.0.0.0"
      FUNCNODES_WORKER_MANAGER_PORT: "9380"
      FUNCNODES_HOST: "0.0.0.0"
      FUNCNODES_WS_WORKER_STARTPORT: "9382"
      FUNCNODES_UPDATE_PACKAGES: ""
    volumes:
      - ./funcnodes_config:/usr/local/app/.funcnodes

For single-worker mode, remove the worker-manager port and expose one worker port:

services:
  funcnodes:
    image: ghcr.io/linkdlab/funcnodes:latest
    ports:
      - "8000:8000"
      - "9382:9382"
    environment:
      FUNCNODES_DOCKER_MODE: "single-worker"
      FUNCNODES_RUNSERVER_HOST: "0.0.0.0"
      FUNCNODES_RUNSERVER_PORT: "8000"
      FUNCNODES_SINGLE_WORKER_HOST: "0.0.0.0"
      FUNCNODES_SINGLE_WORKER_PORT: "9382"
      FUNCNODES_UPDATE_PACKAGES: ""
    volumes:
      - ./funcnodes_config:/usr/local/app/.funcnodes

Start the service:

mkdir -p funcnodes_config
docker compose up

Run in the background:

docker compose up -d

Stop the service:

docker compose down

To pin a release, change the image tag:

image: ghcr.io/linkdlab/funcnodes:v1.6.0

You can also download the example file: docker-compose.yaml.

Configuration Volume

The container uses:

FUNCNODES_CONFIG_DIR=/usr/local/app/.funcnodes

Mounting ./funcnodes_config to that path makes worker configuration persistent across container restarts. Do not mount this directory read-only.

Runtime Package Updates

The image installs the funcnodes release version at build time. If a dependency package has a newer compatible release, set FUNCNODES_UPDATE_PACKAGES to upgrade it when the container starts:

environment:
  FUNCNODES_UPDATE_PACKAGES: "funcnodes-react-flow"

Multiple packages can be separated by spaces:

environment:
  FUNCNODES_UPDATE_PACKAGES: "funcnodes-react-flow funcnodes-worker"

Runtime updates are useful when a dependency package was released independently of the main funcnodes package. They make startup depend on PyPI availability, so keep the value empty for reproducible deployments.

Updating

For latest, pull the newest image and restart:

docker compose pull
docker compose up -d

For pinned deployments, edit the image tag in docker-compose.yaml, then run the same commands.