Skip to content

Docker Agent Setup

Marc Pope edited this page Apr 24, 2026 · 1 revision

Docker Agent Setup

For hosts where the normal agent installer isn't practical — TrueNAS Scale, Synology DSM, UGreen NAS, unRAID, or any appliance OS where you can't persist a system-installed package — the BBS agent is available as a Docker image. It's the same bbs-agent.py you'd install on Linux, packaged with all supported backup tools (borg, ssh, MySQL, PostgreSQL, and MongoDB clients).

Image

docker.io/marcpope/borgbackupserver-agent:latest

Tags:

  • :latest — tracks the most recent AGENT_VERSION on main
  • :<version> — pinned, e.g. :2.25.1
  • :sha-<shortsha> — pinned to a specific commit, useful for debugging

Multi-arch: linux/amd64 and linux/arm64.

Requirements

  • Docker 20.10 or newer (Docker Compose v2 recommended)
  • Network reachability from the container to your BBS server
  • An agent entry in BBS with its API key (Clients → Add Client)

Quick Start (docker-compose)

services:
  bbs-agent:
    image: marcpope/borgbackupserver-agent:latest
    container_name: bbs-agent
    hostname: my-nas              # shown in the BBS UI; set whatever you want
    restart: unless-stopped
    environment:
      BBS_SERVER: https://backups.example.com
      BBS_API_KEY: abc123def456...
    volumes:
      # Persist the SSH key the server issues on first registration.
      - bbs-agent-config:/etc/bbs-agent

      # Bind-mount the paths you want to back up at the SAME path inside
      # the container. Backup plans in BBS reference these host paths.
      - /data:/data:ro
      - /etc:/etc:ro

      # Optional: a writable restore target.
      - /restore:/restore

volumes:
  bbs-agent-config:

Start it:

docker compose up -d

Within a few seconds the agent registers and appears online in the BBS UI under the hostname you set. Create a backup plan against /data (or any other mounted path) and trigger a backup — it runs exactly like a native-installed agent would.

Why mirror mounts?

Mount the host paths you want to back up at the same path inside the container. This is the simplest and most robust pattern:

  • Backup plans in BBS reference /data, /etc, etc. — the paths that appear in archives match what you see on the host.
  • Restores land where you expect them (on the bind-mounted path).
  • Moving the same plans to a natively-installed agent later just works — no path rewriting.

Don't mount everything at a single root like /:/backup_root:ro. That forces your backup paths inside BBS to become /backup_root/..., which is meaningless outside the container and makes cross-migration painful.

Path scope = mount scope. The agent can only see what's mounted in. If you only want it to back up /srv/shares, only mount /srv/shares. No additional configuration is needed to restrict scope.

Restores

Restores need write access. Either:

  • Back up and restore to the same directory (mount it rw rather than ro), or
  • Define a dedicated /restore mount (as in the Quick Start) and target it in the BBS restore UI.

Database restores (MySQL, PostgreSQL, MongoDB) connect over the network to the live database server — make sure the container can reach it (usually on your Docker network or via network_mode: host).

Environment variables

Variable Required Description
BBS_SERVER yes Full URL of your BBS server (trailing slash ignored).
BBS_API_KEY yes API key shown in BBS when you created the client.
BBS_POLL_INTERVAL no Poll interval in seconds. Defaults to 30 if unset.

The entrypoint renders /etc/bbs-agent/config.ini from these on startup. If you prefer to bake a pre-made config into the image, override the entrypoint or bind-mount your own config file.

Hostname

The agent registers itself using the container's hostname (socket.gethostname()). Set hostname: in your compose file to something descriptive — that's what appears in the BBS client list and in archive names.

How updates work

There are two independent update paths, and they coexist intentionally:

  1. Server-pushed agent updates. When BBS wants to update an agent (e.g., after a server upgrade that expects a newer agent protocol), it tells the running agent to replace its own bbs-agent.py. Inside the container this update is written to the container's overlay filesystem, takes effect after the in-place restart, and keeps the agent in sync with the server — which is what you want for day-to-day protocol alignment.

  2. Image pulls. When you docker pull a newer image tag, the container resets to whatever bbs-agent.py was baked in at image build time. The image version tracks AGENT_VERSION from the repo, and a new image is published automatically whenever that version bumps.

In practice: the server keeps your agent current between image updates, and pulling a new image gives you a clean baseline that matches a server upgrade. You only need to pull a new image when you're upgrading your BBS server.

Troubleshooting

Agent doesn't appear in BBS

Check docker logs bbs-agent. Common causes:

  • BBS_SERVER unreachable from the container — test with docker exec bbs-agent curl -I $BBS_SERVER.
  • Wrong API key — the registration step logs HTTP 401 on a bad key.
  • DNS resolution failing inside the container (see [Errno -2] Name or service not known in the logs). Add a dns: entry in compose or use an IP address.

Backups say "path not found"

The path shown in the backup plan isn't mounted into the container. Confirm the path is in volumes: and that the host side actually exists.

Restores land in the wrong place

The restore target path must be bind-mounted rw. A read-only mount will silently fail or produce permission errors.

"Cannot open /var/log/bbs-agent.log"

Not a concern — the Docker agent logs to stdout (captured by docker logs). The log-file path is only used on native installs.


Next: Linux Agent Setup | Backup Plans | Restoring Files

Clone this wiki locally