ippo

Caddy as a webdav and file server

Caddy as a webdav and file server

Caddy as a WebDAV and file server with basic auth , allowed DNS, basic auth and logs.


  • Caddy does not include webdav module by default so you have to build the caddy executable including the webdav handler with xcaddy tool. link to the unofficial module is here

Dockerfile

1
2
3
4
5
6
7
8
9
10
FROM caddy:builder AS builder

# Add WebDAV plugin
RUN xcaddy build \
    --with github.com/mholt/caddy-webdav

FROM caddy:latest

# Copy the custom Caddy binary
COPY --from=builder /usr/bin/caddy /usr/bin/caddy

Caddyfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
:8080 {
    root * /data

    # Replace 'basicauth' with 'basic_auth'
    basic_auth / {
        user password_hash
    }

    # Use a route block for WebDAV
    route {
        webdav
    }

    # Host-based access control
    @allowedHosts host example.org
    respond @allowedHosts "Access Denied" 403

log {
        output file /var/log/caddy/access.log
        format json
        level info
    }
}

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
version: "3.9"
services:
  caddy:
    image: caddy-webdav
    user: 1000:1000
    ports:
      - "8043:8080"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - /run/media/ippo/TOSHIBA:/data
      - ./logs:/var/log/caddy  # Mount logs directory
    restart: unless-stopped

Password hash

docker exec -it caddy-webdav caddy hash-password --plaintext "your_password_here"

Tips

  • Where caddy-webdav the container name or Id

  • Host-based access control : your ddns goes here

  • If you need http directory browsing and static file serving you can use the file_server directive

In this case you need matchers if you route the same path for file server and webdav and if plan to use others directives in your Caddyfile like reverse proxy.

  • The order also matters , WebDAV should go first.

  • In my usecase I use caddy in host for reverse proxy and this container for file_serving and webdav

Caddyfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
:8080 {
    root * /data

    route /* {

# order matters handle webdav first

# Match WebDAV clients first
        @webdavClients not header User-Agent *Mozilla*
        webdav @webdavClients

        # Match browser requests and serve a directory listing
        @browserRequests header User-Agent *Mozilla*
        file_server browse
}

# Authentication
    basicauth / {
        user password_hash
    }

# Host-based access control
    @allowedHosts host example.com
    respond @allowedHosts "Access Denied" 403

    # Logging
    log {
        output file /var/log/caddy/access.log
        format json
        level info
    }
}

Diferent routes example

1
2
3
4
5
6
7
8
9
# WebDAV access
    route /some_dir* {
        @webdavClients not header User-Agent *Mozilla* webdav @webdavClients
    }

    # Directory browsing
    route /some_dir* {
        @browserRequests header User-Agent *Mozilla* file_server browse
    }

comments powered by Disqus