The most useful property of a static deployment is that an operator can answer “which directory served this response?” without reading application code. Caddy’s root and file_server directives provide that boundary directly.

A complete directory is verified before becoming the Caddy root, while the prior known-good directory is retained through smoke tests. A dashed publication tree contains HTML, text and assets. An outward symlink can expose an outside target readable by the service user. Private files remain outside the tree; separate edge checks cover status, content type, redirects, certificate names and missing-route behavior.
Make the serving directory explicit. Audit symlinks and read/traverse permissions, then verify the actual response at the edge.

Make the root explicit

A minimal site block can be kept close to the artifact layout:

www.example.test {
    root * /srv/example-site
    encode zstd gzip

    header {
        -Server
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
    }

    file_server
}

The hostname and path are placeholders; www.example.test is not a publicly issuable production name. Use an owned, resolvable hostname for production and plan local TLS trust separately for a test environment. The release command should publish a complete directory, verify it, and only then make that directory the configured root. Keep the prior known-good directory until the new one has passed smoke tests.

Check the edge, not only the file tree

Request an HTML page, a downloadable text file, and a missing path. Compare content types and status codes with the local artifact. A 404 page that returns 200 is a deployment bug even if the page looks polished.

When Caddy manages HTTPS, certificate provisioning and HTTP-to-HTTPS redirects are part of the edge behavior. Test the redirect from the bare HTTP listener and the certificate name from the public hostname. Do not infer success from a healthy process alone.

A root is a publication boundary, not a sandbox

Keep source control metadata, backups, credentials, and private configuration outside the published tree. Caddy follows symlinks inside the root, so a link can expose files outside it. Check both the artifact contents and the serving user’s read/traverse permissions. Also, merely placing 404.html in the tree does not configure a custom error handler; verify the missing-route status and error-page behavior you intend.

Sources