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.
curlandpython3on 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