Docker (optional)
Docker is optional. Use it only if you want a containerized gateway or to validate the Docker flow.Is Docker right for me?
- Yes: you want an isolated, throwaway gateway environment or to run Fased on a host without local installs.
- No: you’re running on your own machine and just want the fastest dev loop. Use the normal install flow instead.
- Sandboxing note: agent sandboxing uses Docker too, but it does not require the full gateway to run in Docker. See Sandboxing.
- Containerized Gateway (full Fased in Docker)
- Per-session Agent Sandbox (host gateway + Docker-isolated agent tools)
Requirements
- Docker Desktop (or Docker Engine) + Docker Compose v2
- At least 2 GB RAM for image build (
pnpm installmay be OOM-killed on 1 GB hosts with exit 137) - Enough disk for images + logs
Containerized Gateway (Docker Compose)
Quick start (recommended)
Clone the repo, then run from repo root:- builds the gateway image
- runs CLI onboarding
- prints dashboard, token, and pairing hints
- starts the gateway via Docker Compose
- generates a gateway token and writes it to
.env
FASED_DOCKER_APT_PACKAGES— install extra apt packages during buildFASED_EXTRA_MOUNTS— add extra host bind mountsFASED_HOME_VOLUME— persist/home/nodein a named volume
- Open
http://localhost:18789/in your browser. - Paste the token from
.envor the dashboard link if the browser asks for one. - In the UI, finish setup from the selected Agent: Models first, then Chat.
- Need the URL again? Run
docker compose run --rm fased-cli dashboard --no-open.
~/.fased/~/.fased/workspace
Manual flow (compose)
docker compose ... from the repo root. If you enabled
FASED_EXTRA_MOUNTS or FASED_HOME_VOLUME, the setup script writes
docker-compose.extra.yml; include it when running Compose elsewhere:
Control UI token + pairing (Docker)
If you see “unauthorized” or “disconnected (1008): pairing required”, fetch a fresh dashboard link and approve the browser device:Setup after Docker starts
Use the browser UI for normal setup:- open
http://localhost:18789/ - choose the default Agent, shown as Assistant
- configure model auth in Agent > Models
- test one message in Chat
- add channels in Agent > Channels
- add API connectors in Agent > Services
Extra mounts (optional)
If you want to mount additional host directories into the containers, setFASED_EXTRA_MOUNTS before running docker-setup.sh. This accepts a
comma-separated list of Docker bind mounts and applies them to both
fased-gateway and fased-cli by generating docker-compose.extra.yml.
Example:
- Paths must be shared with Docker Desktop on macOS/Windows.
- Each entry must be
source:target[:options]with no spaces, tabs, or newlines. - If you edit
FASED_EXTRA_MOUNTS, rerundocker-setup.shto regenerate the extra compose file. docker-compose.extra.ymlis generated. Don’t hand-edit it.
Persist the entire container home (optional)
If you want/home/node to persist across container recreation, set a named
volume via FASED_HOME_VOLUME. This creates a Docker volume and mounts it at
/home/node, while keeping the standard config/workspace bind mounts. Use a
named volume here (not a bind path); for bind mounts, use
FASED_EXTRA_MOUNTS.
Example:
- Named volumes must match
^[A-Za-z0-9][A-Za-z0-9_.-]*$. - If you change
FASED_HOME_VOLUME, rerundocker-setup.shto regenerate the extra compose file. - The named volume persists until removed with
docker volume rm <name>.
Install extra apt packages (optional)
If you need system packages inside the image (for example, build tools or media libraries), setFASED_DOCKER_APT_PACKAGES before running docker-setup.sh.
This installs the packages during the image build, so they persist even if the
container is deleted.
Example:
- This accepts a space-separated list of apt package names.
- If you change
FASED_DOCKER_APT_PACKAGES, rerundocker-setup.shto rebuild the image.
Power-user / full-featured container (opt-in)
The default Docker image is minimal and runs as the non-rootnode user. This
keeps the attack surface small, but it means:
- no system package installs at runtime
- no Homebrew by default
- no bundled Chromium/Playwright browsers
- Persist
/home/nodeso browser downloads and tool caches survive:
- Bake system deps into the image (repeatable + persistent):
- Install Playwright browsers without
npx(avoids npm override conflicts):
FASED_DOCKER_APT_PACKAGES instead of using --with-deps at runtime.
- Persist Playwright browser downloads:
- Set
PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwrightindocker-compose.yml. - Ensure
/home/nodepersists viaFASED_HOME_VOLUME, or mount/home/node/.cache/ms-playwrightviaFASED_EXTRA_MOUNTS.
Permissions + EACCES
The image runs asnode (uid 1000). If you see permission errors on
/home/node/.fased, make sure your host bind mounts are owned by uid 1000.
Example (Linux host):
Faster rebuilds (recommended)
To speed up rebuilds, order your Dockerfile so dependency layers are cached. This avoids re-runningpnpm install unless lockfiles change:
Channel setup (optional)
Use Agent > Channels in the Control UI for normal setup. It mirrors the current channel onboarding flow and keeps account credentials separate from Agent routing. For scripted Docker setups, you can still run channel CLI commands through the CLI container, then restart the gateway if that command changed runtime config. Docs: WhatsApp, Telegram, DiscordOpenAI Codex OAuth (headless Docker)
If you pick OpenAI Codex OAuth from Agent > Models, it opens a browser URL and tries to capture a callback onhttp://127.0.0.1:1455/auth/callback. In
Docker or headless setups that callback can show a browser error. Copy the full
redirect URL you land on and paste it back into the auth prompt to finish auth.
Health check
FASED_GATEWAY_TOKEN from .env; the
health command reads runtime config/env and does not take a --token flag.
E2E smoke test (Docker)
QR import smoke test (Docker)
Notes
- Gateway bind defaults to
lanfor container use. - Dockerfile CMD uses
--allow-unconfigured; mounted config withgateway.modenotlocalwill still start. Override CMD to enforce the guard. - The gateway container is the source of truth for sessions (
~/.fased/agents/<agentId>/sessions/).
Agent Sandbox (host gateway + Docker tools)
Deep dive: Sandboxing This is separate from running the whole Gateway in Docker. The Gateway can run on the host while selected tool sessions run inside Docker containers.- one sandbox per agent by default
- sandbox workspace under
~/.fased/sandboxes - Docker network disabled by default
- host browser/camera/canvas are blocked by default
denytool policy wins overallowscope: "shared"disables cross-session isolation
Build the default sandbox image
fased-sandbox:bookworm-slim using deploy/containers/Dockerfile.sandbox.
Optional sandbox images
If you want a sandbox image with common build tooling (Node, Go, Rust, etc.), build the common image:fased-sandbox-common:bookworm-slim. To use it:
Custom sandbox image
Build your own image and point config to it:Isolation notes
- Hard wall only applies to tools (exec/read/write/edit/apply_patch).
- Host-only tools like browser/camera/canvas are blocked by default.
- Allowing
browserin sandbox breaks isolation (browser runs on host).
Troubleshooting
- Image missing: build with
scripts/sandbox-setup.shor setagents.defaults.sandbox.docker.image. - Container not running: it will auto-create per session on demand.
- Permission errors in sandbox: set
docker.userto a UID:GID that matches your mounted workspace ownership (or chown the workspace folder). - Custom tools not found: Fased runs commands with
sh -lc(login shell), which sources/etc/profileand may reset PATH. Setdocker.env.PATHto prepend your custom tool paths (e.g.,/custom/bin:/usr/local/share/npm-global/bin), or add a script under/etc/profile.d/in your Dockerfile.