Server agent
The small program that runs on each of your servers, connects out to Relay and carries out deploys.
What the agent is
The agent is a Node.js program, built into a single file, that runs on each server you enroll. It is installed as a systemd service named relay-agent. It drives Docker on the server to pull, start and health-check your containers, and it writes the Caddy configuration that routes traffic to them. The control plane decides what should run. The agent makes it happen.
How it connects
- Outbound only. The agent opens a WebSocket to
wss://<control-plane>/agentand keeps it open. The agent code does not listen on any port, so there is no inbound management port. - Enrollment. On its first start with an enrollment token, the agent sends the server's details to the control plane, receives a persistent agent token and saves it to
/etc/relay/agent-token. Later starts use that saved token. - Heartbeat. Every 15 seconds by default, the agent reports CPU, memory and disk use and the Relay containers it finds on the server.
- Reconnects. If the connection drops, the agent retries with a growing delay, starting at one second and capped at 30 seconds.
- Revocation. If the control plane removes the agent, it exits without reconnecting, and systemd does not restart it.
Install command
Run this on the server, with the two placeholders replaced:
curl -fsSL $RELAY_URL/install.sh | sudo sh -s -- $RELAY_URL $TOKENRELAY_URLis the public base URL of the Relay control plane, the address where its API is reachable. The installer downloads the agent from it and derives the WebSocket address from it.TOKENis an enrollment token created in the dashboard. It starts withenr_and expires 32 hours after it is created.- Running the command with only the URL on a server that is already enrolled upgrades the agent in place and keeps the server's identity.
The installer ends by following the agent's log until you press Ctrl+C. Detaching does not stop the agent.
What the installer does
- Checks that it runs as root and that it received the right arguments.
- Installs Node.js 22 if Node.js is missing or older. This step is automatic on Debian and Ubuntu only.
- Warns if Docker is missing. The installer does not install Docker.
- Installs Caddy if it is missing, on Debian and Ubuntu only, and enables it. The root Caddyfile is set to import
relay-sites/*.caddy. - Downloads the agent to
/opt/relay-agent/agent.mjs, writes its environment file and systemd unit, and startsrelay-agent.
What the agent does on your server
- Receive. The agent accepts a deploy or rollback command, and a stop command for a project, over its WebSocket.
- Pull. If the image is not already on the server, the agent pulls it through the Docker socket.
- Start. The agent stops and removes the project's running container, then starts the new one with the service port published on the host. The agent reports this step as "brief downtime".
- Health check. The agent requests your health check path on
127.0.0.1every 500 milliseconds for up to 10 seconds. Any response with a status below 500 counts as healthy. - Route. After a healthy deploy, the agent writes one Caddy site file per project into
/etc/caddy/relay-sites/, reverse-proxying the project's domains to the container port, and reloads Caddy. Caddy serves those domains over HTTPS. Rollbacks do not rewrite the Caddy files. - Recover. If the health check fails, the agent removes the new container, restarts the last version that passed, and reports the deploy as failed with the reason.
- Clean up. The agent keeps the three most recent stopped containers for each project and removes older ones.
Requirements
- Linux with systemd. The installer uses
systemctl,journalctland a unit file in/etc/systemd/system. - Root. The installer exits unless it runs as root, so use
sudo. - Node.js 22 or newer. Installed automatically on Debian and Ubuntu. On other systems, install it before running the command.
- Docker. Without it the agent still connects, but it cannot deploy.
- Caddy, with ports 80 and 443 reachable. Installed automatically on Debian and Ubuntu. Caddy needs port 80 and port 443 to be reachable from the internet to obtain certificates.
- CPU architecture. The installer does not restrict it. The agent reports its operating system and architecture to the control plane. Images are built for
linux/amd64andlinux/arm64, as described in the deploy loop. - Outbound access. The server needs to reach the control plane, your container registry, and
api.ipify.org, which the agent uses to find the server's public IPv4 address unlessRELAY_PUBLIC_IPis set.
Files on the server
| Path | Contents |
|---|---|
/opt/relay-agent/agent.mjs | The agent program. |
/etc/relay/agent.env | The control plane WebSocket address and the Caddy settings. |
/etc/relay/agent-token | The agent's persistent token, readable only by root. |
/etc/systemd/system/relay-agent.service | The systemd unit that runs the agent. |
/etc/caddy/relay-sites/ | One Caddy site file per project. |
Next steps
- Self-hosting notes cover the control plane and enrolling a server.
- The deploy loop walks through a deploy from git push to healthy traffic.