Help · Operators

Updating the Agent

Agents update themselves: a systemd agent checks for a new version every 6 hours, and a Docker install's Watchtower container takes the new image once a night, between 23:00 and 06:00 UTC. Once the image is out, you can update a Docker agent at once with docker compose pull.

example
Docker, update now:
  cd /opt/proofkit-dvpn
  docker compose pull
  docker compose up -d

The agent is updated differently depending on how it was installed.

systemd (bare metal)

The agent asks ProofKit for the current version 30 seconds after it starts and every 6 hours after that. When there is a newer build, it downloads it, checks its SHA-256 checksum, replaces its binary and restarts. Restarting the service (systemctl restart dvpn-agent) makes it check straight away.

Docker

The agent inside a container does not replace itself. The install sets up a Watchtower container next to it, which checks the agent image every 6 hours and restarts the agent on a newer one. ProofKit releases a new agent image once a night, at 23:00 UTC, so a Docker install updates between 23:00 and 06:00 UTC, each server once. Once the image is out, you can update at once:

  1. SSH into the server and cd /opt/proofkit-dvpn.
  2. docker compose pull fetches the new image.
  3. docker compose up -d restarts the agent on it.
  4. docker compose logs -f --tail 50 shows it connecting again.

One container or two

A node's Docker stack has one of two layouts. In the single layout the agent and the VPN processes (Xray, nginx, WARP) share one container, so each agent update recreates it and cuts every connection through the node. In the split layout they run in two containers, dvpn-agent and dvpn-dataplane: an agent update restarts only the agent, and the connections go on. Only a new image of the data plane, which is released a few times a year and in the same nightly window, cuts them. A new install runs the split layout when the agent image it pulls is new enough, and an older node moves with one command, at a quiet hour, with one cut:

  1. curl -fsSL https://proofkit.org/install.sh | bash -s -- --split-data-plane pulls both images, saves the compose file as docker-compose.yml.pre-split.bak, writes the new one and starts the stack.
  2. curl -fsSL https://proofkit.org/install.sh | bash -s -- --rollback-layout puts the saved file back, with one more cut.

Both commands need no token, and either leaves a node alone that is in the layout it names. A node whose Checks tab shows Data plane is a node that can move. See Node checks.

A split node has two images to keep up to date: the agent's (dvpn-agent) and the data plane's (dvpn-dataplane). Both are released in the same nightly window, and Watchtower recreates only the container whose image moved. A night with a new agent image restarts the agent and none of the processes it asks the data plane for: Xray, nginx and WARP keep running. A night with a new data-plane image restarts those processes once, which cuts the node's connections once, and when both images are new on one night it is that one cut. docker compose pull and docker compose up -d do the same at once, and naming the service (docker compose pull dvpn-agent, then docker compose up -d dvpn-agent) updates the agent alone.

Pinning a version

Each build is published as :latest, as its version number, and as :sha-<commit>. Set IMAGE_TAG in /opt/proofkit-dvpn/.env to pin one, and run docker compose up -d. The data plane of a split node has its own DATAPLANE_TAG in the same file. The node stays registered; only the agent changes.

The dashboard shows the version each agent reports. ProofKit's admins can also push an update to the whole network at once.