Docker Deployment — Vulpine-Box
Vulpine-Box packages the VulpineOS runtime, Vulpine browser, 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/vulpine --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 Vulpine browser distribution first.
# The Dockerfile expects dist/vulpine-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 -dOpen the web panel from your local machine:
open http://your-vps:8443Connect with the remote TUI:
vulpineos remote --url http://your-vps:8443 --api-key $VULPINE_API_KEYThe web panel prompts for the same access key passed in as VULPINE_API_KEY.
What You Need Before docker compose up
Dockerfile.vulpinebox does not compile the browser. It copies a prebuilt browser bundle
from dist/vulpine-linux/ into the image at build time.
Required layout:
VulpineOS/
dist/
vulpine-linux/
vulpine
vulpine-bin
...other runtime files...If dist/vulpine-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
8443is published from the container VULPINE_API_KEYis passed through tovulpineos serve- the stock compose file serves plain HTTP on
8443 - the healthcheck hits
http://localhost:8443/health - Xvfb provides a display so the Vulpine browser 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 normalizes that to ws://.../ws.
Persistent Volumes
| Volume | Path | Purpose |
|---|---|---|
vulpineos-data | /root/.vulpineos | Config, SQLite vault, agent records, logs, and runtime state |
vulpine-profiles | /opt/vulpineos/profiles | Browser profiles, warmed state, and disk cache |
Data survives container restarts. To start fresh, remove the volumes:
docker compose down -vWhat’s Inside
The multi-stage Dockerfile builds:
- Stage 1 — Go binary compilation (
CGO_ENABLED=0, stripped) - Stage 2 — Ubuntu 22.04 runtime with:
- GTK/X11 libraries for Firefox rendering
- Xvfb virtual display (headless)
- Pre-built Vulpine browser binary
The runtime image expects the browser executable at ./browser/vulpine, matching the
entrypoint.
Entrypoint
The scripts/entrypoint.sh script:
- Starts Xvfb on display
:99 - Launches
vulpineos serve --binary ./browser/vulpine --port 8443 --no-tls - Adds
--api-key "$VULPINE_API_KEY"when that environment variable is set - Replaces
--no-tlswith--tls-certand--tls-keywhen both TLS environment variables are set
The panel does not have a separate login database. The prompt in the web panel is asking
for the same access key passed in as VULPINE_API_KEY.
Open http://your-vps:8443, enter the access key, and the panel stores it only
for the current browser session.
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:roThen 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.pemOnce TLS is enabled:
- open
https://your-vps:8443in your browser for the web panel - use the same
https://...base URL withvulpineos remote - the remote TUI normalizes that base URL to
wss://.../ws
Known Limits
- The image depends on a prebuilt Linux Vulpine browser distribution; the Docker build does not produce one for you.
- The stock compose file does not include TLS certificates.
docker-compose.ymlrequiresVULPINE_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
- Remote Access — WebSocket server mode and client connection
- Getting Started — install and launch your first agent
- Architecture — single-process runtime overview