Seafile Private Cloud: Host a High-Performance File Sync Server in Docker
Deploy Seafile using Docker Compose. Access, sync, and share files across your devices with high speed, data integrity, and a clean web GUI.
Deploying Seafile using Docker Compose is the most reliable way to run a private cloud sync service with dedicated caching (Memcached) and database (MariaDB) containers. Below is the step-by-step technical implementation to deploy, configure, and secure Seafile behind a reverse proxy with WebDAV support.
Directory Layout and Prerequisites
To keep deployments organized and data persistent, establish a structured directory layout under /opt. This structure isolates MariaDB database files and Seafile configuration/data files.
sudo mkdir -p /opt/seafile-data/{mysql,shared}
cd /opt/seafile-data/
/opt/seafile-data/mysql: Persistent storage for MariaDB databases./opt/seafile-data/shared: Mount point for all Seafile configuration files, block storage, and logs.
Docker Compose Configuration
Create a docker-compose.yml file to orchestrate the services. This setup uses: 1. MariaDB 10.11: Pinning a stable LTS version prevents data corruption from unexpected minor version upgrades. 2. Memcached 1.6: Used by Seahub to store session states, user profiles, and file listings. 3. Seafile 11.0.8 (Multi-Container): The main Seafile application engine.
Create /opt/seafile-data/docker-compose.yml and add the following configuration:
version: '3.8'
services:
db:
image: mariadb:10.11
container_name: seafile-mysql
environment:
- MYSQL_ROOT_PASSWORD=8lF843h9Vg9pzTzdsY5m2sXn
- MYSQL_LOG_CONSOLE=true
volumes:
- /opt/seafile-data/mysql:/var/lib/mysql
networks:
- seafile-net
restart: always
memcached:
image: memcached:1.6.18
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
- seafile-net
restart: always
seafile:
image: seafileltd/seafile-mc:11.0.8
container_name: seafile
ports:
- "127.0.0.1:8001:80"
- "127.0.0.1:8080:8080"
volumes:
- /opt/seafile-data/shared:/shared
environment:
- DB_HOST=db
- DB_ROOT_PASSWD=8lF843h9Vg9pzTzdsY5m2sXn
- TIME_ZONE=Etc/UTC
- SEAFILE_ADMIN_EMAIL=admin@example.com
- SEAFILE_ADMIN_PASSWORD=1MlDh3wDcfH3Kiy0qFOIXNZq
- SEAFILE_SERVER_LETSENCRYPT=false
- SEAFILE_SERVER_HOSTNAME=seafile.example.com
depends_on:
- db
- memcached
networks:
- seafile-net
restart: always
networks:
seafile-net:
driver: bridge
Configuration Details:
- Port bindings (
127.0.0.1:8001:80): Binds the container's internal Nginx port80to127.0.0.1:8001on the host. This prevents port conflicts and forces all traffic through the host's reverse proxy. - Port bindings (
127.0.0.1:8080:8080): Maps the internal Seafdav (WebDAV) port to the host. SEAFILE_SERVER_LETSENCRYPT=false: Disables the container's internal Let's Encrypt generation, since certificate termination is handled at the host's reverse proxy level.
Initial Deployment and Database Initialization
Start the containers to run the database migrations and generate configuration files:
docker compose up -d
Monitor the initialization logs to verify that the databases (ccnet_db, seafile_db, seahub_db) are created and the administrator account is initialized successfully:
docker compose logs -f seafile
Once the log outputs show that the startup process is complete, stop the container to modify configuration files:
docker compose down
Configuring Seafdav for WebDAV Access
WebDAV is essential for syncing Seafile libraries as network drives on clients like Windows Explorer, macOS Finder, or mobile WebDAV tools.
By default, WebDAV is disabled inside the Seafile container. To enable it:
- Open
/opt/seafile-data/shared/seafile/conf/seafdav.confusing a text editor. - Modify the
[WEBDAV]block as follows:
[WEBDAV]
enabled = true
port = 8080
fastcgi = false
share_name = /seafdav
enabled = true: Activates the internal seafdav server.port = 8080: Sets seafdav to listen on port 8080, matching the mapped port indocker-compose.yml.fastcgi = false: Configures the server to handle standalone HTTP traffic instead of FastCGI, simplifying reverse-proxy routing.
Tuning Seahub Configurations for Reverse Proxying
Because Seafile will serve traffic over HTTPS behind a reverse proxy, you must adjust configuration paths in /opt/seafile-data/shared/seafile/conf/seahub_settings.py to prevent mixed-content blocks and CSRF validation errors.
Append or edit the following options in seahub_settings.py:
SERVICE_URL = 'https://seafile.example.com'
FILE_SERVER_ROOT = 'https://seafile.example.com/seafhttp'
CSRF_TRUSTED_ORIGINS = ["https://seafile.example.com"]
Explanation of Settings:
SERVICE_URL: Defines the base URL for the web GUI.FILE_SERVER_ROOT: Instructs client browsers to download and upload files via HTTPS using/seafhttp. If left as HTTP, modern browsers will block uploads as mixed-content.CSRF_TRUSTED_ORIGINS: Essential for Seafile v9, v10, and v11 to prevent403 Forbiddenerrors during file upload and login processes.
Start the containers back up to apply configurations:
docker compose up -d
Nginx Reverse Proxy Configuration
Install Nginx on the host VPS:
sudo apt update
sudo apt install nginx -y
Create an Nginx configuration file for your Seafile domain under /etc/nginx/sites-available/seafile.conf:
server {
listen 80;
server_name seafile.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name seafile.example.com;
ssl_certificate /etc/letsencrypt/live/seafile.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seafile.example.com/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# Performance & File Transfer Optimizations
client_max_body_size 0; # Disables request body size verification for large file uploads
proxy_read_timeout 36000s;
proxy_connect_timeout 36000s;
proxy_send_timeout 36000s;
send_timeout 36000s;
# Seahub Web UI & API
location / {
proxy_pass http://127.0.0.1:8001;
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-Proto $scheme;
}
# Seafile File Server (Internal fileserver handles /seafhttp uploads/downloads)
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://127.0.0.1:8001/seafhttp;
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-Proto $scheme;
}
# Seafdav (WebDAV)
location /seafdav {
proxy_pass http://127.0.0.1:8080/seafdav;
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-Proto $scheme;
proxy_read_timeout 36000s;
proxy_connect_timeout 36000s;
proxy_send_timeout 36000s;
}
}
Enable the site and verify your Nginx configuration syntax:
sudo ln -s /etc/nginx/sites-available/seafile.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
Ensure your SSL certificates exist under the paths configured. If you do not have certificates yet, use certbot to generate free Let's Encrypt certificates before reloading Nginx:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d seafile.example.com
Verifying the Setup
- Web GUI Access: Navigate to
https://seafile.example.com. Log in using the administrator email and password configured in yourdocker-compose.yml. - File Sync & Uploads: Try uploading a file through the browser to test if the
/seafhttproute resolves correctly under HTTPS. - WebDAV Mount: Open a WebDAV client (e.g., Cyberduck) or mount a network drive directing to
https://seafile.example.com/seafdavusing your administrator login details.