Skip to content

Latest commit

 

History

History
96 lines (70 loc) · 4.02 KB

deployment.md

File metadata and controls

96 lines (70 loc) · 4.02 KB

Deployment

Meta runs each Muse in a per-user secure VM. Locally, a container is the nearest equivalent: the agent sees only its data directory and its workspace.

Docker

cp .env.example .env && $EDITOR .env      # API key
openmuse config init                      # or copy config/config.example.toml to config/config.toml
docker compose up -d app                  # the phone app on http://<host>:8787
docker compose logs app                   # shows the URL with the access token

Other entry points:

docker compose run --rm muse                      # terminal chat
docker compose run --rm muse run "plan my week"   # one task
docker compose up -d daemon                       # advance goals on a timer, no UI

The image runs as a non-root user with all capabilities dropped. Two volumes hold state: openmuse-data (memory, goals, vault, audit log, threads) and ./workspace (the agent's files). config/config.toml is mounted read-only. Set OPENMUSE_SERVER_TOKEN in .env so the token is stable across restarts, and open the printed URL from your phone using the host's address.

Without cloning — the published image (linux/amd64 and linux/arm64, so a Raspberry Pi or an Apple-silicon Mac works):

docker run -d --name muse -p 8787:8787 --env-file .env \
  -v openmuse-data:/data -v "$PWD/workspace:/workspace" \
  ghcr.io/openmuseagent/openmuse:latest
docker logs muse                          # the URL with the access token

:latest and :X.Y.Z follow releases; :edge follows main. Without a mounted config.toml the image starts from config.example.toml, so the model is set from .env (OPENMUSE_LLM_*) or in the app's Connections screen.

With a browser. The -browser tags (:latest-browser, :X.Y.Z-browser, :edge-browser; linux/amd64) bundle Chromium and Playwright and start with the browser tool on, so the agent can use websites and you can watch and take over from the phone (see the app → browser view). It is about 400 MB larger. OPENMUSE_BROWSER_ENABLED=1 is what switches the tool on in that image; the same variable works anywhere Playwright and Chromium are installed.

Building by hand:

docker build -t openmuse .
docker build --build-arg WITH_BROWSER=1 -t openmuse:browser .   # with Chromium
docker run -d --name muse -p 8787:8787 --env-file .env \
  -v openmuse-data:/data -v "$PWD/workspace:/workspace" \
  -v "$PWD/config/config.toml:/app/config/config.toml:ro" openmuse

Keeping it running without Docker

A user-level systemd unit is enough:

# ~/.config/systemd/user/openmuse.service
[Unit]
Description=OpenMuse
After=network-online.target

[Service]
WorkingDirectory=%h/OpenMuse
ExecStart=%h/OpenMuse/.venv/bin/openmuse serve --host 0.0.0.0 --no-qr
Restart=on-failure
EnvironmentFile=%h/OpenMuse/.env

[Install]
WantedBy=default.target
systemctl --user enable --now openmuse
loginctl enable-linger $USER          # keep it running after logout
journalctl --user -u openmuse -f

Reaching it from outside your network

Do not expose port 8787 to the internet directly. Options that keep the token scheme intact:

  • Tailscale / WireGuard: bind to 0.0.0.0, open the tailnet address on your phone.
  • Reverse proxy with TLS (Caddy, nginx): proxy / and /ws (WebSocket upgrade) to 127.0.0.1:8787. The token still applies.

TLS is also what turns on push notifications on the phone: browsers only allow a service worker and Web Push in a secure context (https:// or localhost). A Tailscale address with tailscale serve or a Caddy block like the one below is enough:

muse.example.com {
    reverse_proxy 127.0.0.1:8787
}

Updating

uv tool upgrade openmuse                               # PyPI install (or: pip install -U openmuse)
git pull --ff-only && uv pip install -e ".[dev]"      # source install
docker compose build && docker compose up -d app       # Docker

Data formats (SQLite, JSONL, JSON) are kept backward compatible within a minor version.