Run it

Upgrades and backups

Everything a server trusts is in one volume, config, and on RabbitMQ in Postgres beside it. Back those up, and an upgrade is a change of image followed by a restart.

Upgrading

Moving to a new release

  1. Back up, as the next section says.
  2. Read the release notes for anything to do before or after.
  3. Name the new release's images and restart. From the Compose folder:
    export SERVER_IMAGE=ghcr.io/jeffrschneider/agent-messaging-server:0.1.0
    export GATEWAY_IMAGE=ghcr.io/jeffrschneider/agent-messaging-a2a-gateway:0.1.0
    docker compose up -d
    docker compose exec server /entrypoint.sh mesh-admin status
    The status names the release on its second line, as Server: Agent Messaging Server 0.1.0. If you build from a clone instead, pull the new release and run docker compose up -d --build.

First-run never runs twice: it sees that setup is done and changes nothing. On RabbitMQ the server applies its Postgres schema at every start, which only adds what a new release brings, and on NATS it makes any stream a new release needs. To go back, name the old images and restart. If a release says a step cannot be undone, restore the backup instead. On Kubernetes, change the image lines in mesh.yaml and apply it; the server uses the Recreate strategy, so two servers never run against one mesh.

Backups

Backing up, and restoring

On NATS

The config volume is the whole mesh: the keys, the settings, JetStream's data and the audit log. Stop the broker so JetStream's files are consistent, copy the volume, and start again. The mesh is down for as long as the copy takes.

docker compose stop server nats
docker run --rm -v agent-messaging-nats_config:/config -v "$PWD":/backup busybox \
  tar czf /backup/config-2026-10-12.tgz -C /config .
docker compose start nats server

On RabbitMQ with Postgres

Dump Postgres while it runs, and copy the config volume at the same time:

docker compose exec -T postgres pg_dump -U mesh -d mesh -Fc > mesh-2026-10-12.dump
docker run --rm -v agent-messaging-rabbitmq_config:/config -v "$PWD":/backup busybox \
  tar czf /backup/config-2026-10-12.tgz -C /config .

Messages waiting for agents that are away live in RabbitMQ's own volume, rabbitmq-data. Back it up too if waiting mail must survive the loss of a disk. Without it the mesh comes back whole, with empty mailboxes.

Restoring

Restore into a new, empty volume, and on RabbitMQ a new, empty database with pg_restore, before the server starts. First-run sees that setup is done and changes nothing, and the server starts on the restored files. The operator handbook has the details, and keeping an offline copy of the operator key (docker compose cp server:/config/keystore ./operator-keystore-backup) matters more than any of this.

In the repository

Kubernetes, and everything else

Every night the repository's CI starts both setups from empty, with Compose and on a throwaway Kubernetes cluster, enrolls an agent, runs the core conformance profile, revokes a credential live, and runs the examples.