Deploying wigolo using Docker for Self-Hosting: Complete Setup Guide

Deploy wigolo by pulling the official image ghcr.io/knockoutez/wigolo, mounting a persistent volume at /data, setting a secure WIGOLO_API_TOKEN, and running the container with the serve command bound to 0.0.0.0:3333 using the Docker Compose configuration in packaging/compose.serve.yml.

wigolo is an open-source Node.js daemon that powers AI agents through both MCP (stdio) and HTTP REST interfaces. According to the KnockOutEZ/wigolo repository source code, the project provides a multi-stage Dockerfile with default (slim) and full targets, enabling flexible self-hosting strategies from ephemeral containers to persistent production daemons.

Choose Your Deployment Mode

The repository supports three distinct Docker deployment patterns based on your infrastructure requirements:

  • One-off stdio client: Use docker run -i --rm for quick, stateless tasks where the container exits after completion. The Chromium browser and models download on first use into the mounted volume.
  • Persistent HTTP daemon: Run via Docker Compose for long-running services that expose REST endpoints to multiple clients. This mode binds to 0.0.0.0 inside the container and includes health checks defined in packaging/compose.serve.yml.
  • Full image (pre-installed browser): Build with --target full to embed the Chromium binary directly in the image, eliminating volume dependencies for --rm scenarios or read-only filesystems.

Pull the Docker Image

Start by fetching the latest slim image from the GitHub Container Registry:

docker pull ghcr.io/knockoutez/wigolo

This pulls the default (slim) target. The image remains lightweight because the browser binary and on-device models are cached on first use rather than baked into the layers, as specified in the root Dockerfile.

Configure Data Persistence

Create a named Docker volume to persist data across container restarts:

docker volume create wigolo-data

The Dockerfile declares VOLUME ["/data"], mounting this directory inside the container. This location stores the Chromium binary, on-device models, encrypted keys, and cache files, ensuring they survive image updates and container recreation.

Set Up Authentication

The wigolo daemon implements a fail-closed security model: it refuses to bind to non-loopback interfaces unless authentication is configured. Generate a secure random token:

export WIGOLO_API_TOKEN=$(openssl rand -hex 32)

For production deployments, avoid passing tokens via environment variables directly. Instead, use the WIGOLO_API_TOKEN_FILE option to mount a secret file, as demonstrated in the packaging/compose.serve.yml configuration.

Launch with Docker Compose

For production-grade self-hosting, use the provided Compose file which includes health checks and proper networking:

docker compose -f packaging/compose.serve.yml up -d

The packaging/compose.serve.yml file defines several critical configurations:

  • Command: Executes ["serve","--host","0.0.0.0","--port","3333"] to expose the daemon to external traffic
  • Port mapping: Binds host port 3333 to container port 3333
  • Environment: Sets WIGOLO_DATA_DIR=/data and optionally injects WIGOLO_API_TOKEN
  • Healthcheck: Probes the /health endpoint (defined at lines 49-58) to monitor daemon readiness

To customize authentication, edit the compose file to uncomment either:

WIGOLO_API_TOKEN: "your-secure-random-token"

Or the more secure secret file approach:

WIGOLO_API_TOKEN_FILE: /run/secrets/wigolo_token

Verify and Access the Service

Confirm the container is healthy by querying the health endpoint:

curl -s http://localhost:3333/health

A 200 OK response indicates the Node.js daemon is operational. The Docker Compose health check will automatically restart the container if this endpoint returns unhealthy status codes.

Once running, wigolo exposes two primary interfaces on port 3333:

  • MCP endpoint: http://localhost:3333/mcp for stdio-based agent communication
  • REST API: http://localhost:3333/v1/... for HTTP-based interactions

All requests must include the bearer token in the Authorization header:

curl -H "Authorization: Bearer $WIGOLO_API_TOKEN" \
     -X POST -d '{"query":"example search"}' \
     http://localhost:3333/v1/search

Running Behind a Reverse Proxy

If you run wigolo behind a reverse proxy (such as Nginx or Traefik) that handles authentication, disable the internal token requirement by setting:

WIGOLO_SERVE_ALLOW_UNAUTHENTICATED: "1"

Only enable this when your external proxy enforces strict authentication, as the daemon will accept anonymous requests from any source when this variable is set.

Update wigolo

When new versions are released, update without losing cached data:

docker pull ghcr.io/knockoutez/wigolo
docker compose -f packaging/compose.serve.yml up -d --force-recreate

The wigolo-data volume persists the browser binary and model files, so only the application code updates while the cache remains intact.

Build the Full Image Target

For environments where volume mounts are impossible, build the full target which embeds Chromium:

docker build --target full -t wigolo:full .
docker run -i --rm -p 3333:3333 \
  -e WIGOLO_API_TOKEN=$WIGOLO_API_TOKEN \
  wigolo:full serve --host 0.0.0.0 --port 3333

This approach, defined in the root Dockerfile, produces a larger image but executes immediately without downloading dependencies, making it ideal for ephemeral CI/CD pipelines or restricted filesystems.

Summary

  • Pull the slim image from ghcr.io/knockoutez/wigolo for standard deployments, or build the full target for volume-less execution
  • Mount a persistent volume at /data to cache the Chromium binary, models, and encrypted keys across restarts
  • Secure the daemon by setting WIGOLO_API_TOKEN when binding to non-loopback interfaces, or use WIGOLO_API_TOKEN_FILE for production secrets management
  • Deploy using packaging/compose.serve.yml for automated health checks and proper port exposure on 0.0.0.0:3333
  • Verify deployment via the /health endpoint before routing production traffic

Frequently Asked Questions

What is the difference between the slim and full Docker images?

The slim image (default) downloads the Chromium browser binary and on-device models on first use, storing them in the /data volume. This keeps the initial image size small but requires a writable volume. The full image, built by targeting docker build --target full, embeds the browser binary directly into the image layers according to the Dockerfile specification, making it suitable for ephemeral containers or environments where volume mounts are restricted, though it results in a significantly larger download size.

Why does wigolo require an API token for Docker deployments?

According to the source code implementation in the KnockOutEZ/wigolo repository, the daemon refuses to start on non-loopback interfaces (0.0.0.0) unless the WIGOLO_API_TOKEN environment variable or WIGOLO_API_TOKEN_FILE secret is provided. This fail-closed security model prevents accidental exposure of the MCP and REST endpoints to untrusted networks. When running behind a reverse proxy that handles authentication, you can disable this requirement by setting WIGOLO_SERVE_ALLOW_UNAUTHENTICATED=1.

How do I persist data when updating the wigolo container?

Create a named Docker volume (e.g., wigolo-data) and mount it at /data inside the container as specified in the Dockerfile (VOLUME ["/data"]). When updating images using docker pull and recreating containers with docker compose up -d --force-recreate, attach the same volume to the new container instance. The browser binary, cached models, and encrypted keys stored in /data remain intact across updates.

Where is the Docker Compose configuration located in the repository?

The production-ready Docker Compose configuration is located at packaging/compose.serve.yml in the KnockOutEZ/wigolo repository. This file includes the recommended command arguments (serve --host 0.0.0.0 --port 3333), health check definitions probing the /health endpoint, and example configurations for both environment variable and file-based secret injection appropriate for self-hosting deployments.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →