Skip to content
Beau Barker edited this page Jul 27, 2025 · 19 revisions

WebDAV, or Web-based Distributed Authoring and Versioning, is a set of extensions to the HTTP protocol that allows users to edit and manage files on a web server.

Build Caddy with caddy-webdav

caddy/Dockerfile

FROM caddy:builder AS builder

RUN xcaddy build \
    --with github.com/ggicci/[email protected]

# Final lightweight image
FROM caddy:latest

COPY --from=builder /usr/bin/caddy /usr/bin/caddy

# Copy our Caddyfile into the image
COPY Caddyfile /etc/caddy/Caddyfile

Then:

docker compose build caddy

Compose file

Add a volume:

compose.yaml

volumes:
  user_uploads:

Add the volume to the caddy service:

compose.yaml

- user_uploads:/uploads:rw

Caddyfile

Add a section:

caddy/Caddyfile

handle /uploads/* {
  route {
    root * /uploads
    webdav {
      prefix /uploads
    }
  }
}

Why not use handle_path and remove prefix? Because without prefix there are issues with caddy-webdav (renaming files and directories).

📝 Note you don't need file_browser because WebDAV itself implements GET, PUT, etc. but you may still want file_browser serve if you want regular browsers to be able to click around and download files.

Restart Caddy:

docker compose restart caddy

Authentication

WebDAV can use Basic Auth.

Hash a password:

caddy hash-password --plaintext 'demo'

Add an environment variable:

.env

# WebDAV
WEBDAV_HASHED_PASS='(your hash)'

Add a basicauth section to the Caddy route:

caddy/Caddyfile

handle /uploads/* {
  basicauth {
    demo {env.WEBDAV_HASHED_PASS}
  }
  route
bin/caddy hash-password --plaintext 'secretpass'

Restart Caddy:

docker compose restart caddy
Clone this wiki locally