Runner

Install a Protoline Runner

Install and enroll a Protoline runner on a pre-provisioned Linux host.

What the runner does

protoline-runner connects your infrastructure to Protoline. It polls Protoline for assigned work, validates the target-local policy, executes approved jobs, and reports status back to the control plane.

For the first customer install path, the runner is designed for a pre-provisioned Linux host with Docker Compose already installed. The installer does not install Docker, create Linux users, change group membership, or open inbound network ports.

Requirements

  • A Linux AMD64 host.
  • A non-root user account for the runner.
  • curl and python3 on the host.
  • Docker Engine and Docker Compose already installed if this runner will execute Compose deployments.
  • Docker access for the runner user without sudo.
  • A one-time enrollment token from the Protoline app.

Security note: Docker group access is effectively host-admin access. Use a dedicated runner host where possible, and use separate runner installs for dev and production environments.

Get an enrollment token

Open the Protoline app and create a runner enrollment token for the target you want this host to serve. The app shows the exact command for your organization and target.

Enrollment tokens are one-time secrets. Create a new token if the old one expires or is exposed.

Install

Run the installer as the non-root runner user:

curl -fsSL https://protoline.ai/protoline-install-runner.sh -o protoline-install-runner.sh
chmod +x protoline-install-runner.sh
ENROLLMENT_TOKEN=prte_... ./protoline-install-runner.sh

The installer downloads the runner binary, verifies its SHA-256 checksum, enrolls the runner, writes local configuration, validates the target policy, and starts a user-level systemd service when available.

Installed paths

The default install is user-owned:

Path Purpose
~/.local/bin/protoline-runner Runner binary
~/.config/protoline-runner/target-policy.json Target-local policy
~/.config/protoline-runner/update.json Update settings
~/.local/state/protoline-runner Credentials, state, and runtime files

Verify the runner

Check the installed version:

~/.local/bin/protoline-runner version

Check the user service:

systemctl --user status protoline-runner

Follow runner logs:

journalctl --user -u protoline-runner -f

The runner should appear in the Protoline app after its first heartbeat.

Common options

Set optional environment variables before running the installer:

Variable Default Use
CONTROL_PLANE_URL https://app.protoline.ai/api Protoline API endpoint
RUNNER_ENVIRONMENT inferred from username, else dev Environment class for the generated target policy
ENABLE_COMPOSE 1 Enable Compose execution when Docker checks pass
ENABLE_EDGE_CONNECTOR 1 Enable outbound public app connector when Docker checks pass
INGRESS_NETWORK protoline-public Docker network used for routed app traffic
ALLOWED_PROJECT_PREFIX pl- Required prefix for generated Compose project names

Example:

RUNNER_ENVIRONMENT=prod \
INGRESS_NETWORK=protoline-public \
ENROLLMENT_TOKEN=prte_... \
./protoline-install-runner.sh

Upgrade

Runners report available updates, but v1 installs do not silently upgrade by default. To install an available update:

~/.local/bin/protoline-runner check-upgrade
~/.local/bin/protoline-runner upgrade --restart systemd_user

You can also rerun the installer with a fresh enrollment token when you want to replace the local install cleanly.

Troubleshooting

If the runner installs but does not execute Compose jobs, check Docker access:

docker compose version
docker ps
id -nG

The runner can still enroll and heartbeat without Docker access, but Compose execution is disabled until Docker checks pass.

If the service stops when the SSH session ends, enable lingering for the runner user:

loginctl enable-linger "$(id -un)"
systemctl --user restart protoline-runner