Skip to content

Command line

Pingclair is one binary. Every task, from running the server to checking a configuration, is a subcommand of it:

Terminal window
pingclair <command> [<args…>]

Angle brackets mark a required value, square brackets an optional one, and … a value that can be repeated. Every command accepts --help, and pingclair help <command> prints the same text. Running the binary with no command prints the list of commands.

📌 This page describes v0.2.2. Behavior that changed from the 0.1.x line and the 0.2.0 release candidates is marked Changed in 0.2.0.

The installer also links the binary as pc, so commands can also be invoked as pc validate, pc service reload, and other pc subcommands. The two are the same program: pc is a symbolic link, not a second binary.

Flag What it does
-v, --verbose Raise the log level to debug for this run. Accepted before or after the command. Unlike caddy -v, it does not print the version.
-h, --help Print the help for the command it is attached to.
-V, --version Print the version. Top level only.
Command What it does
run Run the server in the foreground.
reload Apply an edited configuration through the Admin API and report whether the server accepted it.
start Start a detached copy of the server.
stop Stop a running server through the Admin API.
completion Print a shell completion script.
environ Print the environment the server will see.
list-modules List the modules compiled into this binary.
build-info Print build metadata, including the toolchain.
manpage Write man pages into a directory.
storage export, storage-export Write the certificate store into a tar archive.
storage import, storage-import Restore a certificate store from that tarball.
trust Install the internal CA root into the system trust store.
untrust Remove it again.
respond Serve a fixed response, for development.
reverse-proxy Proxy to an upstream without a configuration file.
file-server Serve a directory without a configuration file.
validate Compile a configuration and report what is wrong with it.
adapt Print the compiled JSON form of a Pingclairfile.
fmt Format a Pingclairfile, or show what formatting would change.
hash-password Produce a password hash for basic_auth.
version Print the version.
service Control the installed systemd unit.

storage export and storage import are Caddy’s spellings of storage-export and storage-import; both spellings run the same command.

Runs the server in the foreground with one configuration document. Logs go to standard output and standard error, and Ctrl-C shuts the server down.

Terminal window
pingclair run [OPTIONS] [PATH]
Argument Default What it does
PATH ./Pingclairfile, then ./Caddyfile Configuration file or directory to load.
Flag What it does
-c, --config <CONFIG> The configuration file, as an alternative to PATH. Giving both is refused. -c - reads standard input.
--adapter <ADAPTER> caddyfile or json. Overrides the format the filename extension implies. JSON uses Pingclair’s own schema, not Caddy’s.
-r, --resume Load the configuration the Admin API last autosaved instead of the file, the way caddy run --resume does. Overrides PATH when both are present.
-w, --watch Check the configuration file’s modification time once a second, and reload after every change. Intended for local development.
Terminal window
pingclair run --watch

Changed in 0.2.0: with no path and neither default file present, run starts with no sites and only the Admin API at 127.0.0.1:2019, as caddy run does. On Unix, that empty process accepts its first plaintext HTTP configuration through POST /load; TLS and HTTP/3 listeners need a file at startup. An explicit path that does not exist still fails, so give the path when a missing file must stop the process. SIGUSR1 has no file to read in this mode, so reload through the Admin API instead.

For a server that outlives the terminal, use the installed unit (Run it as a service).

Sends a configuration file to a running server through the Admin API (POST /load). The server answers the request itself, so the command reports whether the file was applied. A signal cannot do that: systemd can only confirm that it was delivered.

Terminal window
pingclair reload [OPTIONS]
Flag Default What it does
-c, --config <CONFIG> ./Pingclairfile, then ./Caddyfile Configuration file to apply.
--address <ADDRESS> 127.0.0.1:2019 Admin API address.

The running configuration must enable the Admin API with the global admin option; without it there is nothing to reach. When the server cannot apply the new file, most often because a listener was added or moved, the command fails and the previous configuration keeps serving.

Terminal window
sudo pingclair reload -c /etc/Pingclair/Pingclairfile

Starts the server as a background process that keeps running after the shell exits, without a service manager.

Terminal window
pingclair start [OPTIONS]
Flag Default What it does
-c, --config <CONFIG> ./Pingclairfile, then ./Caddyfile Configuration file to load.

The process is detached from the terminal and its output is discarded, so its log is not kept anywhere. On a host with systemd, use the installed unit to capture logs, restart after failures, and track listener readiness. See Run it as a service.

Stops a running server with the Admin API’s POST /stop. Like reload, it needs the admin option in the running configuration.

Terminal window
pingclair stop [OPTIONS]
Flag Default What it does
--address <ADDRESS> 127.0.0.1:2019 Admin API address.

Prints a completion script for one shell. The supported names are exactly the ones the argument accepts: bash, zsh, fish, powershell, elvish.

Terminal window
pingclair completion <SHELL>
Terminal window
pingclair completion zsh > ~/.zfunc/_pingclair

Prints the environment this process inherited, one NAME=value per line, so a value such as PINGCLAIR_TLS_STORE can be checked before a start. Unlike caddy environ, it does not print paths the server computed.

Terminal window
pingclair environ

Lists the modules compiled into this binary. --json prints the same list as JSON, for scripts. --versions, --packages, and -s/--skip-standard are accepted, so scripts written for caddy list-modules run unchanged; every module in this build is standard, so --skip-standard prints nothing.

The admin API appears under Caddy’s own names, and only for the parts that answer here: admin.api.load, admin.api.metrics and admin.api.reverse_proxy. admin.api.pki is deliberately absent, because /pki/ is not served — the listing says what a follow-up request will find, which is why it no longer prints a bare admin-api tag.

Terminal window
pingclair list-modules [--json] [--versions]

Prints build metadata: version, target, and the toolchain that produced the binary. Useful when reporting a defect, because it names the exact build.

Terminal window
pingclair build-info

Writes the man pages into a directory that must already exist. The flag is required, so nothing is written into the current directory by accident.

Terminal window
pingclair manpage --directory /usr/local/share/man/man1

Writes the certificate store into a tar archive. The store is the one named by the storage file_system <path> option of the file given with -c/--config, else by PINGCLAIR_TLS_STORE, or else the data directory of the user running the command. The prefix in the example points a root shell at the service account’s store instead of root’s own. -o - writes the archive to standard output.

Terminal window
sudo PINGCLAIR_TLS_STORE=/var/lib/pingclair/.local/share/pingclair \
pingclair storage-export -o /tmp/store.tar

The archive contains private keys, so it is written mode 600 and must be stored securely, with encryption and appropriate access controls. The TLS guide describes the archive contents and when to move it.

Restores a store from an archive written by storage-export. -i - reads the archive from standard input, and -c/--config <file> names the store the same way as for the export. An import that would restore nothing is refused.

Terminal window
sudo PINGCLAIR_TLS_STORE=/var/lib/pingclair/.local/share/pingclair \
pingclair storage-import -i /tmp/store.tar

Installs the root certificate of the internal authority (tls internal) into the system trust store. Afterwards, clients that use that store accept the certificates the authority issues. The root is read from pki/authorities/local/root.crt in the store named by PINGCLAIR_TLS_STORE.

Changed in 0.2.0: the authority moved to that path and is not migrated from the old internal/ directory. After upgrading from an earlier release, run pingclair trust again on every client that trusted the old root.

Terminal window
sudo PINGCLAIR_TLS_STORE=/var/lib/pingclair/.local/share/pingclair pingclair trust

The HTTPS page covers when this is needed and how to check that it worked.

Removes that root certificate from the system trust store. The issued certificates stay on disk, but clients stop trusting them.

Terminal window
sudo PINGCLAIR_TLS_STORE=/var/lib/pingclair/.local/share/pingclair pingclair untrust

Serves one fixed response (status, headers, and body) for every request. It is meant for development, and for testing a client against an origin that always answers the same way.

Terminal window
pingclair respond [OPTIONS]
Flag Default What it does
-s, --status <STATUS> 200 Status code to return.
-H, --header <HEADERS> none Response header as Field: value. Repeatable.
-b, --body <BODY> empty Response body.
-l, --listen <LISTEN> a random loopback port Listener address.
Terminal window
pingclair respond --status 503 --header 'Retry-After: 30' --body 'down for maintenance'

With no --listen, a free loopback port is chosen and printed, so two development servers never compete for one port.

Proxies a listener to one or more upstreams without a configuration file. --to is required; repeating it spreads requests over several upstreams. The reverse proxy guide describes the equivalent configuration file.

Terminal window
pingclair reverse-proxy [OPTIONS] --to <TO>
Flag Default What it does
--from <FROM> localhost Address to listen on.
--to <TO> required Upstream address. Repeat for several.
--header-up <HEADERS_UP> none Request header to send upstream, as Field: value. Repeatable.
--header-down <HEADERS_DOWN> none Response header to send downstream, as Field: value. Repeatable.
--insecure off Do not verify the upstream’s TLS certificate.
--internal-certs off Issue this listener’s certificates from the internal CA instead of trying a public one.
--disable-redirects off Do not provision the HTTP-to-HTTPS redirect listener.
-c, --change-host-header off Rewrite the upstream Host header to the upstream address, as Caddy does.
Terminal window
pingclair reverse-proxy --from :8080 --to 127.0.0.1:3000

Serves a directory over HTTP without a configuration file.

Terminal window
pingclair file-server [OPTIONS]
Flag Default What it does
--listen <LISTEN> :80 Address to listen on.
--root <ROOT> . Directory to serve.
-b, --browse off Show directory listings.
-d, --domain <DOMAIN> none Serve this domain over HTTPS; requires --listen to be a port.
--access-log off Write one access line per request.
--no-compress off Disable response compression.
--file-limit <FILE_LIMIT> none Maximum number of files shown in a directory listing.
--templates off Render .html files as templates, as Caddy does.
Terminal window
pingclair file-server --root ./public --browse --listen :8080

Compression, caching headers, and single-page-application fallbacks belong in a configuration file; the static site guide covers them.

Compiles a configuration and reports the first problem it finds, without starting the server. The exit status is non-zero when the configuration is refused, so the command works as a gate in a deployment script.

Terminal window
pingclair validate [OPTIONS] [PATH]
Argument Default What it does
PATH ./Pingclairfile, then ./Caddyfile Configuration file or directory to check.
Flag What it does
-c, --config <CONFIG> The configuration file, as an alternative to PATH. -c - reads standard input.
--adapter <ADAPTER> caddyfile or json, overriding the filename extension.

validate reads every certificate and key file the configuration names, parses them, and checks that each key belongs to its certificate, without opening any listener. A malformed file or a mismatched pair fails validation instead of the first handshake. Unlike run, validate with no file and no standard input fails.

Terminal window
sudo pingclair validate /etc/Pingclair/Pingclairfile

Prints the JSON document a Pingclairfile compiles to. This is Pingclair’s own schema, the one validate, run, and the Admin API’s /load accept. Unlike caddy adapt, the output is not Caddy’s {"apps": …} schema, and Caddy cannot load it.

--pretty indents the JSON. adapt runs the same validation as validate before printing, so exit status 0 means this build can load the result. --validate is still accepted and changes nothing.

The exported form changed in 0.2.0: route matchers use a tagged representation, the handle container is spelled pipeline, and the retry policy is printed as one predicate. Documents using earlier representations remain supported.

Terminal window
pingclair adapt [OPTIONS]
Flag Default What it does
-c, --config <CONFIG> ./Pingclairfile, then ./Caddyfile Configuration file to read.
-p, --pretty off Indent the JSON.
--validate off Accepted for compatibility; adapt always validates.
Terminal window
pingclair adapt --pretty --validate

Formats a Pingclairfile and prints the result. With no path, it reads ./Pingclairfile; - reads standard input. The canonical form indents with one tab per level.

fmt exits with status 1 when the input was not already formatted, so it can be used as a formatting check, as with caddy fmt; --overwrite rewrites the file and exits 0.

Changed in 0.2.0: the indent is one tab per level instead of two spaces, so reformatting a file from an earlier release changes its indentation throughout.

Terminal window
pingclair fmt [OPTIONS] [PATH]
Flag What it does
--config <PATH> The file to format; Caddy’s spelling of PATH.
-o, -w, --overwrite Write the formatted text back to the file instead of printing it.
-d, --diff Print a visual diff rather than the formatted file.
Terminal window
pingclair fmt --diff # what would change
pingclair fmt --overwrite # apply it

Produces a password hash for the basic_auth directive. The password is read from standard input when --plaintext is omitted, which keeps it out of the shell history.

Terminal window
pingclair hash-password [OPTIONS]
Flag Default What it does
-p, --plaintext <PLAINTEXT> read from standard input Password to hash.
--algorithm <ALGORITHM> bcrypt bcrypt or argon2id.
--bcrypt-cost <COST> 14 bcrypt cost, 4 to 31. Higher values increase computational cost and resistance to password guessing.
--argon2id-time <TIME> 1 argon2id iterations.
--argon2id-memory <MEMORY> 65536 argon2id memory cost, in KiB.
--argon2id-threads <THREADS> 4 argon2id parallelism.
--argon2id-keylen <KEYLEN> 32 argon2id output length, in bytes.
Terminal window
pingclair hash-password --algorithm argon2id

Paste the output into the directive; the basic_auth entry shows the surrounding syntax.

Prints the version. A release binary prints its tag, such as v0.2.2. A binary built from main prints v0.0.0-dev+<commit>, or v0.0.0-dev when it was built without a git checkout; build-info and list-modules --versions report the same string.

Terminal window
pingclair version

Controls the systemd unit the installer wrote. It wraps systemctl, so either can be used; this subcommand provides the same service operations through pingclair.

Terminal window
pingclair service <start|stop|restart|reload|status>
Subcommand What it does
start Start the unit.
stop Stop the unit.
restart Restart the unit, which is what a changed listener or a process-wide option needs.
reload Send a signal to reload the running server’s configuration file. The result is on the unit’s status line and in the journal, not in this command’s exit code.
status Print the unit’s state.

It works only on Linux with systemd; on any other platform it refuses to run. Run it as a service documents the unit itself.

The command line is defined in one file of the server source, pingclair/src/cli/mod.rs, and this page follows its order. When a command’s flags change there, this page changes with them.