Skip to content

Deploy

This page shows how to deploy Bub as a container: build the image, mount persistent state, and upgrade without losing the plugin project.

The repository ships three files that drive the canonical deployment: Dockerfile, docker-compose.yml, and entrypoint.sh.

  • Docker (or compatible runtime) and docker compose are installed.
  • You have a .env with at minimum BUB_MODEL and either BUB_API_KEY or a provider-specific key — see Configure.
  • For a Telegram deployment, BUB_TELEGRAM_TOKEN and an allowlist are in .env — see Telegram.
cp env.example .env

A minimum .env for a Telegram gateway:

BUB_MODEL=openrouter:openrouter/free
BUB_API_KEY=sk-or-...
BUB_TELEGRAM_TOKEN=123456:abcdef...
BUB_TELEGRAM_ALLOW_USERS=123456789

docker compose loads .env automatically — see the env_file: line in docker-compose.yml.

volumes:
  - ${BUB_WORKSPACE_PATH:-.}:/workspace
  - ${BUB_HOME_HOST:-${HOME}/.bub}:/data
  - ${BUB_AGENT_HOME:-${HOME}/.agents}:/root/.agents
MountPurpose
/workspaceThe directory Bub treats as the working repo. Defaults to the directory you ran docker compose from.
/dataHost bind for Bub’s home directory (history, tapes, plugin project).
/root/.agentsShared skill directory (the agents.md convention).

The compose file sets BUB_HOME=/data inside the container. Use BUB_HOME_HOST when you want the host-side source path to be somewhere other than ~/.bub. Runtime settings for this deployment should live in .env; BUB_HOME does not move Bub’s default config.yml path.

docker compose up -d --build
docker compose logs -f app

The first run takes a few minutes — the image installs system tools (git, node, jq, etc.) and runs uv sync --no-dev --no-editable.

On every container start:

  1. If /workspace/bub-reqs.txt exists, install the listed packages into the image’s venv.
  2. Run bub install with no arguments — this syncs the managed plugin project under /data/bub-project/. New plugin entries in pyproject.toml are picked up here.
  3. If /workspace/startup.sh exists, exec it. Otherwise exec bub gateway.

This means a workspace can override the entrypoint by providing its own startup.sh — useful when you want to run bub chat against a long-lived workspace, or to customize gateway flags:

# /workspace/startup.sh
exec /app/.venv/bin/bub gateway --enable-channel telegram
docker compose ps
docker compose logs -f app | rg "telegram.start polling"

A healthy Telegram deployment logs telegram.start polling once. If it logs nothing channel-related, check that BUB_TELEGRAM_TOKEN reached the container (docker compose exec app env | rg BUB_TELEGRAM).

A rolling upgrade preserves the plugin project under /data (host BUB_HOME_HOST, default ~/.bub):

git fetch --all --tags
git pull
docker compose build --pull
docker compose up -d
docker compose logs -f app

Inside the running container, plugins are managed by bub install and bub update:

docker compose exec app bub install                       # sync project
docker compose exec app bub install owner/repo@v1.2.0     # add or pin a plugin
docker compose exec app bub update                        # upgrade everything
docker compose exec app bub update specific-plugin        # upgrade one

Both commands operate on the managed project at BUB_PROJECT (default bub.home / "bub-project", /data/bub-project in this compose deployment). They never touch the system Python environment.

  • Configure — env-var precedence and provider settings.
  • Telegram — bot token and allowlist behavior.
  • CLI reference — flags for bub gateway, bub install, bub update.