Skip to Content
Docker (Vulpine-Box)

Docker Deployment — Vulpine-Box

Vulpine-Box packages the VulpineOS runtime, OpenClaw, Camoufox, and an Xvfb display into a single container. Use it when you want the browser kernel on a VPS and connect to it from your laptop through the web panel or the TUI.

By default the container starts:

./vulpineos serve --binary ./browser/camoufox --port 8443 --no-tls --api-key "$VULPINE_API_KEY"

That means the stock Docker path exposes the same served control plane as a normal vulpineos serve run. The panel and the remote TUI both authenticate with the same access key.

Quick Start

git clone https://github.com/VulpineOS/VulpineOS.git cd VulpineOS # Build or copy the Linux Camoufox distribution first. # The Dockerfile expects dist/camoufox-linux/ to exist. # Set an access key for the served runtime. export VULPINE_API_KEY=$(openssl rand -hex 32) # Launch the container. docker compose up -d

Open the remote panel from your local machine:

vulpineos remote panel --url http://your-vps:8443 --api-key $VULPINE_API_KEY

Connect with the remote TUI instead:

vulpineos remote tui --url http://your-vps:8443 --api-key $VULPINE_API_KEY

vulpineos remote defaults to panel mode, so vulpineos remote --url ... also works.

What You Need Before docker compose up

Dockerfile.vulpinebox does not compile Camoufox. It copies a prebuilt browser bundle from dist/camoufox-linux/ into the image at build time.

Required layout:

VulpineOS/ dist/ camoufox-linux/ camoufox camoufox-bin ...other runtime files...

If dist/camoufox-linux/ is missing, the Docker build will fail.

Docker Compose

The docker-compose.yml defines the service:

services: vulpineos: build: context: . dockerfile: Dockerfile.vulpinebox ports: - "8443:8443" environment: - VULPINE_API_KEY=${VULPINE_API_KEY:?set VULPINE_API_KEY to a random access key before running docker compose} volumes: - vulpineos-data:/root/.vulpineos - vulpine-profiles:/opt/vulpineos/profiles restart: unless-stopped deploy: resources: limits: memory: 4G volumes: vulpineos-data: vulpine-profiles:

Default behavior:

  • port 8443 is published from the container
  • VULPINE_API_KEY is passed through to vulpineos serve
  • the stock compose file serves plain HTTP on 8443
  • the healthcheck hits http://localhost:8443/health
  • Xvfb provides a display so Camoufox can stay headful inside the container

If you want HTTPS/WSS, mount certificates and provide VULPINE_TLS_CERT and VULPINE_TLS_KEY. Until then, connect with http://... URLs for the panel and let vulpineos remote tui normalize that to ws://.../ws.

Persistent Volumes

VolumePathPurpose
vulpineos-data/root/.vulpineosConfig, SQLite vault, agent records, logs, and runtime state
vulpine-profiles/opt/vulpineos/profilesBrowser profiles, warmed state, and disk cache

Data survives container restarts. To start fresh, remove the volumes:

docker compose down -v

What’s Inside

The multi-stage Dockerfile builds:

  1. Stage 1 — Go binary compilation (CGO_ENABLED=0, stripped)
  2. Stage 2 — Ubuntu 22.04 runtime with:
    • GTK/X11 libraries for Firefox rendering
    • Xvfb virtual display (headless)
    • Pre-built Camoufox binary
    • Node.js + OpenClaw

The runtime image expects the browser executable at ./browser/camoufox, matching the entrypoint.

Entrypoint

The scripts/entrypoint.sh script:

  1. Starts Xvfb on display :99
  2. Launches vulpineos serve --binary ./browser/camoufox --port 8443 --no-tls
  3. Adds --api-key "$VULPINE_API_KEY" when that environment variable is set
  4. Replaces --no-tls with --tls-cert and --tls-key when both TLS environment variables are set

The panel does not have a separate login database. The prompt in the remote panel is asking for the same access key passed in as VULPINE_API_KEY.

If you connect with:

vulpineos remote panel --url http://your-vps:8443 --api-key $VULPINE_API_KEY

the generated URL includes the token, the panel validates it, stores it in session storage, and strips it from the visible URL after load.

Memory

Each browser context uses roughly 10-15 MB. With the 4 GB memory limit, you can comfortably run 20-30 concurrent contexts with headroom for the kernel itself. Adjust the memory limit in docker-compose.yml for larger deployments.

TLS

To enable TLS, mount your certificates:

volumes: - ./certs/fullchain.pem:/etc/vulpineos/cert.pem:ro - ./certs/privkey.pem:/etc/vulpineos/key.pem:ro

Then pass the matching environment variables:

environment: - VULPINE_API_KEY=${VULPINE_API_KEY:?set VULPINE_API_KEY to a random access key before running docker compose} - VULPINE_TLS_CERT=/etc/vulpineos/cert.pem - VULPINE_TLS_KEY=/etc/vulpineos/key.pem

Once TLS is enabled:

  • use https://your-vps:8443 with vulpineos remote panel
  • use the same https://... base URL with vulpineos remote tui
  • the remote TUI normalizes that base URL to wss://.../ws

Known Limits

  • The image depends on a prebuilt Linux Camoufox distribution; the Docker build does not produce one for you.
  • The stock compose file does not include TLS certificates.
  • docker-compose.yml requires VULPINE_API_KEY; generate one before launching the service on a network.
  • Browser rendering happens under Xvfb, so direct desktop inspection is not part of this deployment mode.

See also

Last updated on