Skip to content

Run with Docker

This guide runs Auto Runtime with Docker, the tool that runs packaged programs in isolated environments called containers. You start Auto from its image (Auto Runtime packaged to run in a container) on Docker Hub, check that it responds, connect your agent and sign in through the Auto identity service. Then you add a model provider and give a machine or a pipeline an API key.

You need Docker Engine or Docker Desktop, a terminal, and a browser on the same machine to sign in with.

Choose a variant

The ledger is Auto's record of every playbook, definition and run. The two variants keep it in different places:

VariantWhere the ledger is keptUse it when
One container with a volumeA SQLite file (a database in a single file) on a volumeYou want the quickest start on one machine
Compose with PostgreSQLA PostgreSQL database in a second container beside itYou want the database to take the backups, and the container to keep no files

A volume is storage that Docker keeps apart from any container, so the ledger survives when you replace the container. Compose is Docker's tool for starting several containers from one file.

Run one variant at a time. Both publish port 5555 on this machine, so a second one cannot start while the first runs. Steps 2 and 3 apply to both.

The image

onauto/runtime is published for linux/amd64 and linux/arm64. Each release is published under three tags, the names you pull an image by:

TagPoints to
0.9.1Exactly that release; it never changes
0.9The newest release of the 0.9 line, moving with each fix
latestThe newest release

Pin a full version, such as 0.9.1, so you know what is running, and upgrade on purpose. Every example on this page reads the version from one line you write in step 1. latest moves to each new release; use it only when you mean to run whatever is newest each time you pull.

In the image, Auto:

  • listens on port 5555;
  • runs as the unprivileged user node;
  • keeps a SQLite ledger on the volume at /data, unless you give it a PostgreSQL database;
  • checks its own health at /health;
  • stops cleanly on SIGTERM, the signal Docker sends to ask a program to stop.

1. Start Auto

Make a folder for Auto Runtime's files and work in it. Then choose the release, and write it to .env, a file of settings for the Docker commands on this page:

bash
mkdir auto-runtime && cd auto-runtime
echo 'IMAGE=onauto/runtime:0.9.1' > .env

Replace 0.9.1 with the newest version on the releases page. Every command below takes the image from this line, so an upgrade changes only this line.

People sign in through the Auto identity service. Auto needs the address at which people reach it, PUBLIC_URL, and a key to seal the secrets it keeps under, SECRETS_KEY, 32 random bytes in base64. Put both in auto-runtime.env, the file that holds Auto's own settings, one NAME=value per line. Later steps add to it. A container needs PUBLIC_URL or API_KEYS: it listens on every interface, so without either it stops at start (Who can call a server). Then create a volume for the ledger:

bash
echo 'PUBLIC_URL=http://localhost:5555' > auto-runtime.env
echo "SECRETS_KEY=$(openssl rand -base64 32)" >> auto-runtime.env
docker volume create auto-runtime-data

You will start the container again each time you add a setting or upgrade. Keep the command in a small script, so every restart carries every flag. The script stops and removes the previous container, if there is one, before it starts the new one:

bash
cat > start-runtime.sh <<'EOF'
#!/bin/sh
cd "$(dirname "$0")" || exit 1
. ./.env
if docker container inspect auto-runtime >/dev/null 2>&1; then
  docker stop auto-runtime && docker rm auto-runtime
fi
docker run --detach --name auto-runtime --restart unless-stopped \
  --publish 127.0.0.1:5555:5555 --env-file auto-runtime.env --volume auto-runtime-data:/data \
  "$IMAGE"
EOF
chmod +x start-runtime.sh
./start-runtime.sh

What the script does:

  • . ./.env reads the release you chose, so "$IMAGE" names it.
  • --publish 127.0.0.1:5555:5555 makes port 5555 reachable from this machine only. It publishes the port on the loopback address 127.0.0.1, the machine's own address, which other machines cannot reach. That suits an http PUBLIC_URL (Let people sign in says why). To reach Auto from other machines, follow Put HTTPS in front.
  • --volume auto-runtime-data:/data keeps the ledger on the named volume when the container is replaced. Without it, Docker gives each container an empty anonymous volume, and its playbooks last only as long as that container.
  • --env-file auto-runtime.env passes the settings and secrets. Docker reads the file when it creates the container, so docker restart auto-runtime does not pick up a change to it. Run ./start-runtime.sh instead.

SECRETS_KEY stays out of the volume, so a copy of the volume holds no secret anyone can read without it. Without SECRETS_KEY, Auto would make a key itself, in secrets.key on the volume beside the ledger, where a copy of the volume would carry it. Keep a copy of the key with your other secrets: a secret sealed under a lost key cannot be read again. Where there is no openssl, . ./.env && docker run --rm "$IMAGE" node --print "require('node:crypto').randomBytes(32).toString('base64')" makes one too.

2. Check that it responds

bash
curl http://localhost:5555/health
curl --include http://localhost:5555/v1/orgs/acme/playbooks
  • The first returns {"status":"ok"} and needs no credential.
  • The second is refused with 401, since it sends no credential. Its WWW-Authenticate: Bearer resource_metadata="http://localhost:5555/.well-known/oauth-protected-resource", scope="user:org:read org:read org:write playbook:read playbook:write" header tells an agent where to sign you in.

docker logs auto-runtime, or docker compose logs runtime with Compose, shows what Auto read when it started, one JSON object per line:

  • where the ledger is kept;
  • which model providers are configured;
  • the identity service people sign in through, and the audience of their tokens;
  • a warning for anything missing.

If the check fails, see Troubleshooting.

3. Connect your agent and sign in

Agents connect to Auto's MCP endpoint, the address /mcp. MCP is the protocol agents use to call tools. In Claude Code:

bash
claude mcp add --transport http auto-runtime http://localhost:5555/mcp

In Codex:

bash
codex mcp add auto-runtime --url http://localhost:5555/mcp

The first time your agent connects, it opens the Auto identity service in your browser. Sign in, choose your organization, and grant the permissions on the consent screen. What signed-in people can do describes what you may then do. In Claude Code, /mcp shows whether auto-runtime is connected, and offers the sign-in while it is not.

Then ask your agent to create a playbook, as Build your first playbook does. The MCP reference lists the tools, and the HTTP API lists the same operations over HTTP.

4. Add a model provider

Reasoning functions need a model. Add your provider's key to auto-runtime.env, then replace the container so it reads the file again:

bash
echo 'ANTHROPIC_API_KEY=<your Anthropic key>' >> auto-runtime.env
./start-runtime.sh

OPENAI_API_KEY and GOOGLE_GENERATIVE_AI_API_KEY work the same way. For Amazon Bedrock, Azure OpenAI, Google Vertex AI or a gateway of your own, see Set up a model provider.

Keys for machines and pipelines

A machine or a pipeline does not sign in, so it needs an API key. Create one, add it to auto-runtime.env and replace the container as API keys describes, with the image of step 1 ("$IMAGE" after . ./.env).

Run with PostgreSQL

In this variant the database holds the ledger, and Auto's container keeps nothing of its own. A Compose file runs both, with the database's data on a volume.

  1. If you started the single container, stop and remove it. It holds port 5555:

    bash
    docker stop auto-runtime && docker rm auto-runtime

    The PostgreSQL ledger starts empty. Playbooks kept on the volume auto-runtime-data stay there and are not copied.

  2. If you do not have .env and auto-runtime.env from step 1, create them in a new folder. Replace 0.9.1 with the newest version on the releases page:

    bash
    mkdir auto-runtime && cd auto-runtime
    echo 'IMAGE=onauto/runtime:0.9.1' > .env
    echo 'PUBLIC_URL=http://localhost:5555' > auto-runtime.env
    echo "SECRETS_KEY=$(openssl rand -base64 32)" >> auto-runtime.env

    Auto takes SECRETS_KEY from auto-runtime.env, as in step 1. A ledger in PostgreSQL needs it, and Auto stops at start without it.

  3. Save this as compose.yaml beside auto-runtime.env:

    yaml
    services:
      postgres:
        image: postgres:18
        environment:
          POSTGRES_USER: auto_runtime
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: auto_runtime
        volumes:
          - postgres-data:/var/lib/postgresql
        healthcheck:
          test: ['CMD-SHELL', 'pg_isready --username auto_runtime --dbname auto_runtime']
          interval: 5s
          retries: 12
        restart: unless-stopped
    
      runtime:
        image: ${IMAGE}
        depends_on:
          postgres:
            condition: service_healthy
        env_file: auto-runtime.env
        environment:
          DATABASE_URL: postgresql://auto_runtime:${POSTGRES_PASSWORD}@postgres:5432/auto_runtime
        ports:
          - '127.0.0.1:5555:5555'
        restart: unless-stopped
    
    volumes:
      postgres-data:
  4. Compose reads IMAGE and POSTGRES_PASSWORD from .env in the same folder. Add a generated password to it, then start both:

    bash
    echo "POSTGRES_PASSWORD=$(openssl rand -hex 16)" >> .env
    docker compose up --detach

Auto waits until PostgreSQL is ready and creates its tables when it starts. docker compose logs runtime shows The ledger is kept in PostgreSQL, in the database auto_runtime on postgres:5432. Check it as in step 2 and connect your agent as in step 3.

The Compose file holds every setting of both containers, so you never retype flags. After you change auto-runtime.env, such as adding a model provider's key as in step 4, replace Auto's container:

bash
docker compose up --detach --force-recreate runtime

Use PostgreSQL covers a managed database, a user with only the privileges it needs, and TLS.

Use a configuration file

Some settings are lists or maps, such as the tool servers functions may call, model gateways and model aliases. They can go in a YAML file. The image reads one only when CONFIG_FILE names it, so mount the file read-only and name it.

For the single container, add two lines to the docker run command in start-runtime.sh. The whole script becomes:

bash
#!/bin/sh
cd "$(dirname "$0")" || exit 1
. ./.env
if docker container inspect auto-runtime >/dev/null 2>&1; then
  docker stop auto-runtime && docker rm auto-runtime
fi
docker run --detach --name auto-runtime --restart unless-stopped \
  --publish 127.0.0.1:5555:5555 --env-file auto-runtime.env --volume auto-runtime-data:/data \
  --volume "$PWD/auto-runtime.yaml:/etc/auto-runtime/auto-runtime.yaml:ro" \
  --env CONFIG_FILE=/etc/auto-runtime/auto-runtime.yaml \
  "$IMAGE"

Then run ./start-runtime.sh.

With Compose, add CONFIG_FILE to the environment of the runtime service, and give the service a volumes entry for the file. The other lines of the service stay as they are:

yaml
services:
  runtime:
    environment:
      DATABASE_URL: postgresql://auto_runtime:${POSTGRES_PASSWORD}@postgres:5432/auto_runtime
      CONFIG_FILE: /etc/auto-runtime/auto-runtime.yaml
    volumes:
      - ./auto-runtime.yaml:/etc/auto-runtime/auto-runtime.yaml:ro

Then run docker compose up --detach, which replaces Auto's container because its definition changed.

Rules for the file:

  • Secrets stay in auto-runtime.env. The file refers to them by name, such as ${GATEWAY_API_KEY}.
  • An openapi tool server whose entry in tool_servers names its OpenAPI document by a path reads that document at start, from the directory of the file. Mount the document there too, as --volume "$PWD/billing.json:/etc/auto-runtime/billing.json:ro", or name it by an https URL the container can reach.
  • A document that Auto cannot read stops the start, and the error names the entry.

The configuration reference describes the file and every setting.

Upgrade

The ledger stays on its volume or in its database, and the new version migrates it when it starts.

  1. Read the release notes of the new version.
  2. Change the version on the IMAGE line of .env, such as IMAGE=onauto/runtime:0.9.2.
  3. Replace the container.

For the single container, pull the new release, then run the script. It replaces the container with every flag it had:

bash
. ./.env
docker pull "$IMAGE"
./start-runtime.sh

With Compose:

bash
docker compose pull
docker compose up --detach

After the upgrade:

  • Workflows that were waiting go on once the new version starts.
  • Calls cut off by the stop run again, as Stop describes.
  • When several servers share a database, follow Upgrade several servers.

Rotate the secrets key

To replace SECRETS_KEY, move its value to SECRETS_KEY_PREVIOUS and add a new key:

bash
sed 's/^SECRETS_KEY=/SECRETS_KEY_PREVIOUS=/' auto-runtime.env > auto-runtime.env.next
echo "SECRETS_KEY=$(openssl rand -base64 32)" >> auto-runtime.env.next
mv auto-runtime.env.next auto-runtime.env

Then replace the container: ./start-runtime.sh for the single container, or docker compose up --detach --force-recreate runtime with Compose. At start Auto seals again under the new key what the old one sealed, and docker logs auto-runtime, or docker compose logs runtime, says how many: Secrets are kept sealed under the key <id>, and <count> sealed under the previous key were sealed again under it. Then delete the SECRETS_KEY_PREVIOUS line from auto-runtime.env and replace the container once more. Rotate the secrets key covers several servers.

Back up and restore

For the single container, the ledger on the volume is three files that belong together: ledger.db, ledger.db-wal and ledger.db-shm. Stop Auto, copy the whole volume, and start it again:

bash
docker stop auto-runtime
docker run --rm --volume auto-runtime-data:/data:ro --volume "$PWD/backup:/backup" alpine cp -a /data/. /backup/
docker start auto-runtime

docker stop and docker start keep the same container, with every flag it was created with.

To restore, stop Auto, replace the three files in the volume with the copies, and start it:

bash
docker stop auto-runtime
docker run --rm --volume auto-runtime-data:/data --volume "$PWD/backup:/backup:ro" alpine \
  sh -c 'rm -f /data/ledger.db /data/ledger.db-wal /data/ledger.db-shm && cp -a /backup/. /data/'
docker start auto-runtime

With PostgreSQL, use your database's own backups, or pg_dump. The workflows are in the same database, so one backup holds everything except content kept on object storage, which you back up alongside it. For the Compose variant:

bash
docker compose exec -T postgres pg_dump --username auto_runtime --format custom auto_runtime > ledger.dump

The secrets in a backup open only under the SECRETS_KEY that sealed them, so a restored ledger starts with that key, which you keep apart from the backups.

Stop

docker stop auto-runtime, or docker compose stop runtime with Compose, sends SIGTERM. Auto finishes the work it already accepted, records where its workflows are, and exits, usually in well under a second. Calls it cut off run again when it next starts, except a function run that may have called tools (Retrying under a run id). Starting, stopping and restarting describes the stop in detail.