# Run a Docker Runner Provisioner (https://www.shipfox.io/docs/installation/runner-provisioner)

Description: Start the Shipfox Docker runner provisioner from a source checkout and verify its runner-instance lifecycle.

A [runner provisioner](https://www.shipfox.io/docs/operations/runner-provisioners) creates runner instances,
starts ephemeral compute, and activates each runner for at most one job. You do not
hand a workspace registration credential to the provider. This guide deploys the Docker
provisioner.

## Before you begin [#before-you-begin]

* A Docker daemon the provisioner can control (local socket or a reachable Docker host).
* A runner container image, such as `shipfox-runner:ubuntu22`.
* Access to your workspace settings in the Shipfox dashboard.
* A Shipfox source checkout with `mise install` and `pnpm install` complete.

> **Upgrade order for self-hosted deployments (info)**
> Upgrade the Shipfox API before upgrading the Docker provisioner. The provisioner
> submits stale-created containers as registration-deadline candidates and removes
> them only after the API authorizes termination. Set
> `RUNNER_TERMINATION_REASON_REGISTRATION_DEADLINE_ENABLED=true` on the API before
> upgrading the provisioner; it defaults to `false`. Keep the older provisioner
> running until the API upgrade is complete. On rollback, downgrade the Docker
> provisioner before the API.

## Create a provisioner token [#create-a-provisioner-token]

### Open Settings → Runner Provisioners

In the dashboard, go to **Settings → Runner Provisioners**.

### Create the token

Click **Create token** and copy the value. It is shown only once. Treat it like a
secret. A workspace token can provision only its workspace. An installation token
can serve host-approved workspaces, but the runner still receives its workspace
only after immutable assignment. You can revoke either token on the same page.

## Write a templates file [#write-a-templates-file]

A template maps a label set to the container that provides it. Start with one template:

```yaml
templates:
  docker-ubuntu22-2vcpu:
    labels: [ubuntu22, ubuntu22-2vcpu]
    image: shipfox-runner:ubuntu22
    cpu: 2
    memory: 4GiB
    max_concurrency: 100
    target_concurrency: 0
```

The full field semantics and selection rule live in the [Runner Provisioner reference](https://www.shipfox.io/docs/reference/runner-provisioner#template-file-schema).

## Start the provisioner [#start-the-provisioner]

Start the provisioner from the Shipfox source checkout. Replace the API URL and
token with values from your deployment:

```bash
SHIPFOX_API_URL='<YOUR_SHIPFOX_API_URL>' \
SHIPFOX_PROVISIONER_TOKEN='<YOUR_PROVISIONER_TOKEN>' \
SHIPFOX_PROVISIONER_TEMPLATES_FILE=./templates.yaml \
mise exec -- pnpm --filter=@shipfox/provisioner-docker dev
```

It authenticates on startup, then enters its control loop. On a shutdown signal
it stops claiming new work and exits cleanly. Use your process supervisor to
keep it running. All tuning variables are listed in the [Runner Provisioner
reference](https://www.shipfox.io/docs/reference/runner-provisioner).

## Verify it works [#verify-it-works]

Fire a workflow whose `runner:` label matches one of your templates (for example
`runner: ubuntu22`). Within a few seconds the provisioner creates a runner instance
and starts a container with a one-use bootstrap token. The container enrolls, receives
an immutable assignment, activates, claims one job, runs it, and exits. The run detail
page shows the job leaving `pending` and streaming logs.

## Breaking protocol migration [#breaking-protocol-migration]

Provisioners built against the former capacity protocol must migrate as one release:

1. Replace capacity creation, capacity assignment, and batch registration-token calls
   with runner-instance creation and bootstrap tokens.
2. Start compute with `SHIPFOX_RUNNER_BOOTSTRAP_TOKEN`, never a workspace registration
   token.
3. Attach the provider runner ID, let the runner enroll, then assign its runner instance
   to the owned reservation.
4. Treat an unassigned runner as workspace-neutral. Do not send workspace metadata,
   credentials, or job data through the provider.

Use `SHIPFOX_PROVISIONER_RUNNER_INSTANCE_BATCH_SIZE` in place of
`SHIPFOX_PROVISIONER_REGISTRATION_TOKEN_BATCH_SIZE`. A template may set
`target_concurrency` to maintain prewarmed, unassigned runners independently of demand.

## Related pages [#related-pages]

### [Runner Provisioner reference](https://www.shipfox.io/docs/reference/runner-provisioner)

Every environment variable and the template schema.

### [Runner Provisioners](https://www.shipfox.io/docs/operations/runner-provisioners)

How the control loop works.