Deploy the app
Run the Bub application in a container, mount its data on the host, and choose the gateway channels it starts. Download and unpack the source archive for Bub 0.6.0 from GitHub Releases, then run the commands below from that directory.
The repository ships three files that drive the canonical deployment: Dockerfile, docker-compose.yml, and entrypoint.sh.
Before you begin
Section titled “Before you begin”- Docker (or compatible runtime) and
docker composeare installed. - You have a
.envwith at minimumBUB_MODELand eitherBUB_API_KEYor a provider-specific key: see Configure. - For a Telegram deployment,
BUB_TELEGRAM_TOKENand an allowlist are in.env: see Telegram.
1. Prepare the env file
Section titled “1. Prepare the env file”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.
2. Understand the volumes
Section titled “2. Understand the volumes”volumes:
- ${BUB_WORKSPACE_PATH:-.}:/workspace
- ${BUB_HOME_HOST:-${HOME}/.bub}:/data
- ${BUB_AGENT_HOME:-${HOME}/.agents}:/root/.agents
| Mount | Purpose |
|---|---|
/workspace |
The directory Bub treats as the working repo. Defaults to the directory you ran docker compose from. |
/data |
Host bind for Bub’s home directory (history, tapes, plugin project). |
/root/.agents |
Shared 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.
3. Pull and start
Section titled “3. Pull and start”docker-compose.yml uses the prebuilt image ghcr.io/bubbuild/bub, published to GHCR on every release:
docker compose pull
docker compose up -d
docker compose logs -f app
Image tags follow the release version (0.6.0a2), <major>.<minor> for stable releases, and latest for the newest stable release. Set BUB_IMAGE in .env to pin a version, for example BUB_IMAGE=ghcr.io/bubbuild/bub:0.6.0a2.
To build from your local checkout instead, pass --build. The local build is tagged as BUB_IMAGE, so it replaces the pulled image until the next docker compose pull:
docker compose up -d --build
A local build takes a few minutes — the image installs system tools (git, node, jq, etc.) and runs uv sync --no-dev --no-editable --extra app.
Run without Compose
Section titled “Run without Compose”The image runs the same way with plain docker run. Mount the same volumes and pass .env explicitly:
docker run -d --name bub --restart unless-stopped \
--env-file .env \
-e BUB_HOME=/data \
-v "$PWD":/workspace \
-v ~/.bub:/data \
-v ~/.agents:/root/.agents \
ghcr.io/bubbuild/bub:latest
docker logs -f bub
To upgrade, docker pull the new tag, then docker rm -f bub and rerun the same command.
4. What entrypoint.sh does
Section titled “4. What entrypoint.sh does”On every container start:
- If
/workspace/bub-reqs.txtexists, install the listed packages into the image’s venv. - Run
bub installwith no arguments; this syncs the managed plugin project under/data/bub-project/. New plugin entries inpyproject.tomlare picked up here. - If
/workspace/startup.shexists, exec it. Otherwise execbub 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
5. Verify the running service
Section titled “5. Verify the running service”docker compose ps
docker compose logs -f app | rg "telegram.start polling"
A healthy Telegram deployment logs telegram.start polling once. If there are no channel logs, check that the container received the token without printing it: docker compose exec app sh -c 'test -n "$BUB_TELEGRAM_TOKEN"' returns status 0 when it is set.
6. Upgrade safely
Section titled “6. Upgrade safely”Back up the host data directory before upgrading. Then pull the new image and recreate the container, keeping .env and the host mount paths. The bind mount at /data retains the plugin project (host BUB_HOME_HOST, default ~/.bub):
docker compose pull
docker compose up -d
docker compose logs -f app
If you build locally, run git pull && docker compose build --pull instead of docker compose pull.
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.
Next steps
Section titled “Next steps”- Configure: env-var precedence and provider settings.
- Telegram: bot token and allowlist behavior.
- CLI reference: flags for
bub gateway,bub install,bub update.