After long days and countless hours of effort, I have finally found a configuration that allows Seafile to function seamlessly behind SWAG (Secure Web Application Gateway) as a reverse proxy. This guide is a message to the open-source community, sharing the fruits of my labor to help others achieve the same success.
Environment Information
- Operating System: Ubuntu 24.04.1 LTS
- Docker Version: 27.3.1, build ce12230
- Seafile Community Edition/Pro : 11
- SWAG Network Name: swag_default
- Seafile Working Directory: /opt/seafile/
- Stack Setup: SWAG is in one stack, and Seafile is in another stack.
Step 2: Prepare the Working Directory
I decided to place Seafile in
/opt/seafile/
, where the docker-compose will create the mysql and data directories.
Step 3: Create the docker-compose.yml File
- Create and edit the docker-compose.yml file:
- This can also be copy-pasted into Portainer if you prefer using a GUI.
services:
db:
image: mariadb:10.11
container_name: seafile-mysql
environment:
- MYSQL_ROOT_PASSWORD=db_dev
- MYSQL_LOG_CONSOLE=true
- MARIADB_AUTO_UPGRADE=1
volumes:
- /opt/seafile/mysql/db:/var/lib/mysql
networks:
- seafile-net
memcached:
image: memcached:1.6.18
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
- seafile-net
seafile:
image: seafileltd/seafile-mc:11.0-latest
container_name: seafile
volumes:
- /opt/seafile/data:/shared
environment:
- DB_HOST=db
- DB_ROOT_PASSWD=db_dev
- TIME_ZONE=America/New_York
- SEAFILE_ADMIN_EMAIL=me@domain.com
- SEAFILE_ADMIN_PASSWORD=YourAdminPassword
- SEAFILE_SERVER_LETSENCRYPT=false
- SEAFILE_SERVER_HOSTNAME=seafile.domain.com
- FORCE_HTTPS_IN_CONF=true
depends_on:
- db
- memcached
networks:
- seafile-net
- swag_default
networks:
seafile-net:
driver: bridge
swag_default:
external: true
- seafile-net: Internal bridge network for Seafile services
- swag_default: External network for SWAG integration
This network configuration ensures that Seafile can communicate internally with its database and memcached services, while also being accessible externally through the SWAG reverse proxy.
Step 4: Configure Nginx as a Reverse Proxy
-
My SWAG configuration directory is located at /var/docker_data/swag. You can create the configuration file directly with:
vim /var/docker_data/swag/nginx/proxy-confs/seafile.subdomain.conf
-
We create this file ourselves because no template is provided by SWAG for Seafile. Perhaps the one I provide here will be included in future versions of Seafile.
-
Copy and paste the following content:
server {
listen 443 ssl;
listen [::]:443 ssl;
# Your domain name
server_name seafile.domain.com;
# Or like the official nginx template from SWAG
# server_name seafile.*;
# Include the SSL configuration from SWAG Template
include /config/nginx/ssl.conf;
# No limit for the uploads
client_max_body_size 0;
location / {
# Use the internal Docker DNS resolver
include /config/nginx/resolver.conf;
# Proxy configuration to the Seafile container
set $upstream_app seafile;
# It is 80 and NOT 8080
set $upstream_port 80;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
# Headers necessary for CSRF and other features
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header Connection "";
# For large files
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_send_timeout 36000s;
# Support WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
IMPORTANT:
The seafile.subdomain.conf does not includeinclude /config/nginx/proxy.conf
due to header conflicts.
EDIT 21/12/2024
I’ve significantly improved the Nginx configuration for Seafile behind SWAG:
- Added crucial security headers (HSTS, CSP, Permissions Policy, etc.)
- Optimized proxy settings for better performance
- Ensured compatibility with Seafile’s requirements
Key changes:
- Strict Transport Security (HSTS) enforcement
- Content Security Policy (CSP) implementation
- Referrer Policy and X-Frame-Options for enhanced protection
- Optimized proxy settings for Seafile compatibility
This update provides a more secure and efficient setup for Seafile behind SWAG. Implement these changes to boost your server’s security posture.
server {
listen 443 ssl;
listen [::]:443 ssl;
# Your domain name
server_name seafile.domain.com;
# Include SWAG's standard SSL configuration
include /config/nginx/ssl.conf;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header Cache-Control "no-transform" always;
add_header Content-Security-Policy "upgrade-insecure-requests; frame-ancestors 'self'" always;
add_header Permissions-Policy "interest-cohort=()" always;
add_header Referrer-Policy "same-origin" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-UA-Compatible "IE=Edge" always;
add_header X-XSS-Protection "1; mode=block" always;
client_max_body_size 0;
location / {
# Utilise le resolver DNS interne de Docker
include /config/nginx/resolver.conf;
# Configuration du proxy vers le container Seafile
set $upstream_app seafile;
set $upstream_port 80;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
# Timeout if the real server is dead
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
# Proxy connection settings
proxy_buffers 32 4k;
proxy_connect_timeout 36000s;
proxy_headers_hash_bucket_size 128;
proxy_headers_hash_max_size 1024;
proxy_http_version 1.1;
proxy_read_timeout 36000s;
proxy_redirect http:// $scheme://;
proxy_send_timeout 36000s;
# Proxy cache and cookie settings
proxy_cache_bypass $cookie_session;
proxy_no_cache $cookie_session;
# Client and request identification
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Original-Method $request_method;
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
# Protocol and server information
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-Ssl off;
# Websocket, connection and upgrade management
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
# Host and proxy information
proxy_set_header Host $http_host;
proxy_set_header Proxy "";
# Request and URI management
proxy_set_header X-Forwarded-Uri $request_uri;
proxy_set_header X-Forwarded-Method $request_method;
# SSL optimization
proxy_set_header Early-Data $ssl_early_data;
}
}
Step 5: Configure Seafile
- Modify seahub_settings.py:
- Ensure the “s” is added after “http” in SERVICE_URL and verify that both SERVICE_URL and FILE_SERVER_ROOT are set to your domain name.
...
SERVICE_URL = "https://seafile.domain.com"
...
FILE_SERVER_ROOT = "https://seafile.domain.com/seafhttp"
CSRF_TRUSTED_ORIGINS = ["https://seafile.domain.com"]
- Why CSRF_TRUSTED_ORIGINS is Important:
- CSRF (Cross-Site Request Forgery) is a security measure to prevent unauthorized actions on a web application. By adding CSRF_TRUSTED_ORIGINS, you inform Django (the framework used by Seafile) that requests from your domain are safe.
- This configuration is crucial when Seafile is behind a reverse proxy, as it ensures that legitimate requests are not blocked.
- These resources helped me understand this requirement:
Stack Overflow Explanation : 38842030/12317483
I can’t add link in post
Step 6: Restart the Stack
- Restart the stack to apply all changes:
docker compose down
docker compose up -d
- Everything should now function correctly. Access Seafile at
https://seafile.domain.com
and enjoy your setup!
Changelog:
21/12/2024:
- Major security enhancement: Added crucial security headers
- Implemented HSTS, CSP, Permissions Policy, and other protective measures
- Optimized proxy settings for improved Seafile compatibility and performance
- Updated X-Forwarded-* headers for better request handling
11/12/2024:
- Added Cloudflare compatibility configuration
- Included specific settings for proper functioning behind Cloudflare’s proxy