I've been using Seafile as my self-hosted file sync solution for a while now, and it's been fantastic. But I was using nextcloud before that and while I moved to seafile, I kept nextcloud for one reason: The webdav support. I'm using webdav as zotero attachment storage instead of using their expensive paid storage. I knew that there was a support for webdav in seafile, but I never got around to setting it up.
The documentation exists, but it's written with a traditional installation in mind. When we're running Seafile in Docker with Nginx Proxy Manager handling all our reverse proxy needs, things get a bit more nuanced. After spending sometime figuring out the right configuration, I wanted to document the process, both for future me and anyone else running a similar setup.
My selfhosted infrastructure runs mostly in Docker containers. Seafile lives in its own container with MariaDB and Redis, while Nginx Proxy Manager handles all incoming traffic and SSL certificates. The official Seafile documentation assumes we're either running a bare-metal installation or manually configuring Nginx, neither of which applied to my setup.
The challenge was that I needed to enable WebDAV inside the containerized Seafile instance, configure the correct networking between containers, and set up Nginx Proxy Manager to route WebDAV traffic properly.
Let's walk through each step.
Prerequisites
Before starting, make sure we have:
- Seafile running in Docker (I'm using the official
seafileltd/seafile-mcimage) - Nginx Proxy Manager installed and operational
- Both containers sharing a Docker network
- A working Seafile installation accessible via our domain
If we're starting fresh, we should get Seafile running and accessible through our domain first. This guide assumes we already have that foundation in place.
The first step is creating the WebDAV configuration file. In a containerized Seafile setup, configuration files live in /shared/seafile/conf/ inside the container. This maps to wherever we've mounted our Seafile data volume on the host.
Create the seafdav.conf file. We can do this directly inside the container 1:
docker exec seafile bash -c 'cat > /shared/seafile/conf/seafdav.conf << EOF
[WEBDAV]
enabled = true
port = 8080
debug = true
share_name = /seafdav
workers = 5
timeout = 1200
EOF'Or if we prefer working on the host filesystem:
cat > /path/to/our/seafile_data/seafile/conf/seafdav.conf << 'EOF'
[WEBDAV]
enabled = true
port = 8080
debug = true
share_name = /seafdav
workers = 5
timeout = 1200
EOFThis needs to be adjusted to the location of your Seafile data mount on the host or the docker volume name if we're using one.
Let me break down what each option does:
- enabled: Obvious, turns
WebDAVon or off iffalse - port: The internal port where
WebDAVlistens. Port8080is standard and doesn't conflict with Seafile's main service on port 80 - debug: Enables verbose logging. Useful during initial setup, though we might want to disable it later
- share_name: The URL path where
WebDAVwill be accessible./seafdavis the default - workers: Number of Gunicorn worker processes. Five is reasonable for most home setups
- timeout: How long to wait before timing out a request. 1200 seconds (20 minutes) accommodates large file uploads
Now we need to worry about the networking. This is where Docker setups differ from traditional installations. Our Seafile container needs to be on the same Docker network as Nginx Proxy Manager. In my docker-compose setup, it looks something like this:
services:
seafile:
image: seafileltd/seafile-mc:latest
environment:
- SEAFILE_ENABLE_WEBDAV: true
# Other config stuff...
networks:
- seafile-internal # Private network for database/redis
- proxy-network # Shared with Nginx Proxy Manager
networks:
seafile-internal:
driver: bridge
proxy-network:
external: trueThe key insight: Seafile needs/should have two networks. One internal network for database and Redis communication, and one shared network with our reverse proxy. This allows Nginx Proxy Manager to route traffic to Seafile using the container name as a hostname. The only thing related to WebDAV we should include in our docker-compose file is the environment variable SEAFILE_ENABLE_WEBDAV: true. The rest of the configuration is handled by the seafdav.conf file.
We don't need to expose port 8080 to the host. In fact, we shouldn't. Let Nginx Proxy Manager handle all external access. The containers communicate internally over their shared Docker network. Also since it is external docker network, we have to make sure it is created before running the container. To do that we need to run the following command:
docker network create proxy-networkWith the configuration in place, restart the Seafile container:
docker compose restart seafileGive it a few seconds, then verify WebDAV is actually running:
docker exec seafile netstat -tlnp | grep 8080We should see something indicating port 8080 is listening. We can also check the process directly:
docker exec seafile ps aux | grep seafdavLook for wsgidav.server.server_cli in the output. If we see it, WebDAV is running. If not, check the logs:
docker exec seafile tail -f /shared/logs/seafdav.logNow comes the interesting part. Nginx Proxy Manager's UI makes proxy configuration easy, but WebDAV requires some specific settings that aren't immediately obvious.
We open our NPM admin interface and edit the proxy host for our Seafile domain. We're going to add three locations.
Location 1: The Redirect
First, we need a redirect to ensure URLs with and without trailing slashes work correctly. WebDAV is particular about this.
Click "Add location" and configure:
- Location:
/seafdav - Scheme:
http - Forward Hostname/IP:
seafile(use our container name) - Forward Port:
80
In the "Custom config" section, add:
return 301 $scheme://$host/seafdav/;This redirects /seafdav to /seafdav/ (note the trailing slash). It seems trivial, but WebDAV clients expect this behavior.
Save and test that our main Seafile instance still works. Add one location at a time – if something breaks, we'll know exactly which configuration caused it.
Location 2: The Main WebDAV Handler
This is where the actual WebDAV traffic gets routed. Add another location:
- Location:
^~ /seafdav/ - Scheme:
http - Forward Hostname/IP:
seafile - Forward Port:
8080
The ^~ prefix is important, it's a regex modifier that tells Nginx to stop searching for other location matches once this one is found. This ensures WebDAV requests don't accidentally get caught by other location blocks.
In "Custom config":
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 1200s;
client_max_body_size 0;These headers are crucial. They tell the backend Seafile service about the original request, the real client IP, the protocol (https), and the hostname. Without these, Seafile won't generate correct URLs for WebDAV operations.
The timeout matches what we set in seafdav.conf (1200 seconds), and client_max_body_size 0 removes any upload size limits imposed by Nginx.
Location 3: Directory Browser (Optional)
Seafile includes a web-based directory browser for WebDAV. If we want this functionality:
- Location:
/:dir_browser - Scheme:
http - Forward Hostname/IP:
seafile - Forward Port:
8080
No custom config needed here. I honestly haven't used this feature, but it's nice to have.
At this point, we should be able to access WebDAV at:
https://ourdomain.com/seafdavWe try it in a browser first. We will see basic authentication prompt. We cannot use our normal login credentials. We need go to https://ourdomain.com/profile/#update-webdav-passwd and reset webdav password. It will also give us the WebDAV username which will be also same as our seafile username.
Now we should have a working WebDAV setup. A few things worth mentioning about security:
We should always use HTTPS. WebDAV transmits credentials, and we don't want those going over the wire in plaintext. Nginx Proxy Manager makes this easy. We Also should not expose port 8080 directly to the internet. Let Nginx Proxy Manager be our single entry point. And always use strong passwords for our Seafile accounts. Since WebDAV uses HTTP basic authentication, our password is essentially our only protection.
Or better yet, consider limiting WebDAV access to your local network or VPN if possible. I run everything through Tailscale, so my Seafile instance is only accessible on my private network.
Then we don't have to worry about where did we mount or which docker volume is mapped to /shared/seafile/conf/