Skip to content

Upgrading and removing

Version 0.2.0 changes how existing configurations route, bind, compress, and identify clients. These changes also apply when upgrading from 0.2.0-rc.N. The patch releases 0.2.1 and 0.2.2 change no configuration. Read the complete Before you upgrade list and its linked entries before replacing a binary. The summary below covers the changes most likely to affect a deployment.

Review What to change or expect
Routing Directive order decides the first matching route. A catch-all redir, route, or handle can precede a specific respond. Use exclusive handle blocks or explicit route order.
Paths ASCII case is ignored and escapes are decoded once. handle_path and URI stripping also ignore case. Braces are literal; use path_regexp for captures and case-sensitive routing. Equal-length sibling paths retain file order.
Block matchers handle, handle_path, and route accept only *, /path, or @name. Replace handle *.php with a named path *.php matcher.
Listeners bind applies even with explicit addresses and ports, including the automatic redirect. listen retains its IP address. bind and default_bind allow one address. Sites on one port share a listener; a bind-restricted site beside a wildcard listener is refused.
Addresses A named site with a port and no scheme uses HTTPS. Write http:// for plaintext. Scheme-only addresses use global ports. [::1] names a site, and 0.0.0.0 with [::] on one port folds to IPv6.
Client identity In servers, write trusted_proxies static … once per scope. List CF-Connecting-IP in client_ip_headers when needed. Use client_ip and {client_ip} for the forwarded client; remote_ip and {remote_host} mean the peer. {remote_ip} is refused.
Request limits There is no default body-size ceiling. Set request_body { max_size … } if needed. Header completion and pauses between body reads default to 60 seconds; uploads with long pauses may need a longer limits { body_timeout … }.
Error pages handle_errors now handles gateway, timeout, and 413 errors too. Its root and file_server serve the page with the error status. Restrict a catch-all block by status if appropriate.
Encoding No compression without encode. Blocks, gzip levels (default 5), response matchers, and minimum length take effect. encode off cannot have a block. Static responses always vary by encoding; proxy responses do so on encode sites. Re-encoding weakens proxy ETags; static and sidecar validators change. no-transform disables encoding.
Response cache Freshness includes upstream age. All caching routes must agree on max_size; reload applies budget changes. flush_interval -1 bypasses admission. Every Vary line participates in variants; invalid Vary and Vary: * prevent storage.
Admin API Missing config reads return 200 null. Reads mask secrets, so restore them before loading an export. Config writes honor path-qualified If-Match; after 412, read the path and its ETag again. Reads remain available through reload.
Metrics Add global metrics to collect. Scrapes are empty without it. Update dashboards to the renamed caddy_* families.
CLI Use --config/-c and --adapter caddyfile|json; do not also supply a positional path. With no default file, run starts admin-only. Give an explicit path if absence must fail. validate now parses TLS files and checks key pairs.
TLS The internal CA moves to pki/authorities/local/ without migration: trust the new root again. Exact names no longer inherit wildcard client_auth; add an explicit block if required. Manual TLS requires a named site.
Upstreams Weight 0 drains, weights above 100 and all-zero primary pools fail validation. lb_try_duration bounds new attempts, not an active response. Retries after delivery are limited to idempotent methods.
Protocols CONNECT receives 405 and closes H1; a target without a usable port receives 400. Malformed HTTP/1 targets and chunked bodies receive 400 and close. FastCGI HEAD has no body, oversized parameters receive 431, and malformed bodies abort the response.
Lifecycle Occupied HTTP, admin, and H3 UDP ports prevent startup. SIGTERM drains within grace_period. Restart still has a connection gap; reload is preferable for policy changes.

The known release defects still apply. A 502 or 504 generated by the built-in proxy error path carries Proxy-Status; a custom handle_errors response does not. A missed keepalive reuse is logged at DEBUG rather than ERROR.

Back up the configuration, the current binary, and the entire TLS store before upgrading. Preserve their ownership and protect backups containing private keys. The installer keeps /etc/Pingclair/Pingclairfile, the certificate store at /var/lib/pingclair/.local/share/pingclair, and the site’s files. It replaces the binary, example configuration, and systemd unit, then restarts the service. A configured storage file_system path takes precedence over the usual store.

Keep the old store backup for rollback: trusting the new internal root does not make old clients trust it, and rolling back only the binary does not restore the old root or configuration format.

Run the new binary’s validate against the production configuration while it is still staged, before replacing the running binary. It opens no listeners, but its user must be able to read every certificate and key the file names. Then test the affected routes, case variants, forwarded client identity, error pages, uploads, compression, and metrics in a staging deployment.

A source build of main reports v0.0.0-dev+<sha> (or v0.0.0-dev without a checkout); a release binary reports its tag, such as v0.2.2. Check the tag and published checksum when installing. A dev version string is not evidence that the stable release is installed.

The installer selects the stable channel:

Terminal window
curl -fsSL https://pingclair.com/install.sh | sudo bash
pingclair version
pc service status

Confirm that pingclair version reports v0.2.2, the service is running, and your routes respond as expected.

The installer has no version-pinning flag. For containers, pin the intended tag:

services:
pingclair:
image: ghcr.io/dorianverlaine/pingclair:v0.2.2
Terminal window
docker compose pull
docker compose up -d
docker compose logs pingclair

Keep the configuration and TLS store volumes. latest follows stable releases; alpha previews do not advance it. Host ports must be free before startup.

Stop the new service, restore the backed-up binary, configuration, and TLS store with their original ownership, then validate with the restored binary before starting. A configuration written by 0.2.0 may not load in an earlier version. Do not overwrite a running certificate store with a partial backup.

Terminal window
sudo pc service stop
sudo systemctl disable pingclair
sudo rm /etc/systemd/system/pingclair.service
sudo systemctl daemon-reload
sudo rm /usr/local/bin/pingclair /usr/local/bin/pc

These commands preserve /etc/Pingclair, /var/lib/pingclair, and /var/log/pingclair, including certificates and site files. Delete retained data only when it is no longer needed for reinstall or rollback.