Since v0.3.13 every release publishes nevoflux/agent to Docker Hub, built
for amd64 and arm64, so an Apple Silicon or Graviton host pulls a native
image:
docker pull nevoflux/agent:0.3.13 # a specific releasedocker pull nevoflux/agent:latest # the newest published release
Each published tag pairs a browser release with the agent binary that shipped
alongside it, and is only pushed after that release goes public — so a tag
that exists always corresponds to a release you can download.
Pin the version in production.latest moves under you at the next
release; 0.3.13 does not.
You only need this for a custom build — extra bundled packs, a specific
agent/browser pairing, or unreleased binaries. The image is built from the agent
repo's deploy/headless/ directory and downloads the official prebuilt releases
from GitHub — there is no local compilation:
docker build -t nevoflux/agent:custom deploy/headless # amd64 or arm64
TARGETARCH selects the x86_64 / aarch64 download. On an arm64 host — or with
docker buildx build --platform linux/arm64 — it fetches the arm build
automatically.
To test locally-built or unreleased daemon/browser changes (a feature not yet in a
release), stage the four artifacts into deploy/headless/ and build the
COPY-based variant:
installs bun and bun add <GBRAIN_PIN> into ~/.nevoflux/brain-tool, and creates the brain dir ~/.gbrain;
writes ~/.config/nevoflux/config.toml with [knowledge_base.brain] enabled = true and [llm] provider = <LLM_PROVIDER>.
GBrain's LLM calls route through the in-process gateway to that provider, so no
separate GBrain key is needed — just the provider's *_API_KEY (e.g.
ANTHROPIC_API_KEY) at runtime.
# default: gbrain on, provider anthropic (needs ANTHROPIC_API_KEY at run time)docker build -t nevoflux/agent:latest deploy/headless# another provider, a pin, or disabled:docker build \ --build-arg LLM_PROVIDER=openai \ # then set OPENAI_API_KEY at run time --build-arg GBRAIN_PIN=github:garrytan/gbrain#<sha> \ --build-arg INSTALL_GBRAIN=0 \ # skip gbrain entirely -t nevoflux/agent:latest deploy/headless
If you mount your ownconfig.toml, keep [knowledge_base.brain] enabled = true
and a working [llm] provider, or GBrain won't start. Without a working provider,
browser tasks and brain storage still work, but GBrain's LLM synthesis
(brain_think) won't.
Pack install goes over the daemon's RPC (there is no offline installer), so packs
are cloned into the image at build time and installed at startup once the
daemon is up. This works even with an ephemeral (tmpfs) data dir — packs are
re-applied on each start from the baked-in clones.
docker build -t nevoflux/agent:latest \ --build-arg PACK_REPOS="owner/pack-repo https://github.com/x/y.git" \ deploy/headless# cloned to /opt/packs/<name>; the entrypoint runs `pack install` after the daemon is listening.
PACK_REPOS is space-separated — a GitHub owner/repo shorthand or a full git
URL. No packs are installed if it is empty. See Packs for the pack
format.
/work is where each task's result.json + debug-bundle/ + artifacts are drained.
base-profiles (read-only) holds pre-authenticated login templates, cloned per task.
The container runs read-only; the daemon writes only to the tmpfs mounts above.
The default command is --daemon --headless --http-addr 0.0.0.0:8080, which also
serves the OpenAI-compatible /v1/chat/completions on the same port. To split
OpenAI / MCP / ACP onto their own ports, override the command — see
Task API & interfaces.
Set NEVOFLUX_VNC=1 (and provide a password file) to watch a run live. The image
then runs x11vnc (raw VNC on :5900) andwebsockify serving noVNC on
:6080:
docker run --rm -p 8080:8080 -p 6080:6080 -p 5900:5900 \ -e NEVOFLUX_VNC=1 -e NEVOFLUX_VNC_PASSWD=/etc/nevoflux/vncpasswd \ -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \ nevoflux/agent:latest# watch in any browser: http://localhost:6080/vnc.html# or a native VNC client: localhost:5900
Env
Effect
NEVOFLUX_VNC
1 enables raw VNC (:5900) + noVNC (:6080). Default off.
NEVOFLUX_VNC_PASSWD
Path to the VNC password file (default /etc/nevoflux/vncpasswd).
NEVOFLUX_VNC_VIEWONLY
1 = watch only, no input — so you can't disturb the automation.
Keep VNC off in production. A raw VNC / noVNC port is a remote-control
surface. Only expose it behind an authenticated HTTPS proxy or an SSH tunnel.
The entrypoint (under tini) runs: dbus → Xvfb → (optional VNC) →
GBrain init → daemon. In daemon mode it starts the daemon in the
background, installs any bundled packs once the daemon is listening, then hands
over (forwarding SIGTERM/SIGINT for a clean shutdown). Non-daemon invocations
(e.g. config, pack) run directly.