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:
- SSH into the server and
cd /opt/proofkit-dvpn. docker compose pullfetches the new image.docker compose up -drestarts the agent on it.docker compose logs -f --tail 50shows 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:
curl -fsSL https://proofkit.org/install.sh | bash -s -- --split-data-planepulls both images, saves the compose file asdocker-compose.yml.pre-split.bak, writes the new one and starts the stack.curl -fsSL https://proofkit.org/install.sh | bash -s -- --rollback-layoutputs 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.