Seafile + Docker + Caddy Reverse Proxy on a debian/ubuntu VPS
Seafile is a great alternative to Dropbox, Google Drive or Nextcloud for sharing files
either with your own devices or 3rd parties.
Prerequisites:
Your VPS should already have the minimal configuration including
sshwith PubPriv Keysufwset up with at least: deny all / allow 22, 80, 443 rules in place. Don’t forgetufw enablefail2bandocker&docker-composeset up for your distibutionhostnameset up- probably a domain/subdomain with an A record pointing to your servers IP
1. Install Caddy and set up as reverse proxy
Install and set up Caddy following the official guide:
https://caddyserver.com/docs/install#debian-ubuntu-raspbian
The config file for Caddy should be in /etc/caddy/Caddyfile. You can inspect this file at this point and test if everything
is working: go to your servers IP or domain on port 80. You should now be greeted by Caddy.
You can check if caddy runs with
$ sudo systemctl status caddy
This should return Active: active (running)
2. Create a Docker Network for your Seafile containers
To have all your seafile containers in the same subnet with a static IP, you need to create an (external) docker network.
$ sudo docker network create --driver=bridge --subnet=10.10.10.0/24 --gateway=10.10.10.1 seafile_net
3. Set up Seafile with docker-compose
Local folders
Navigate to your users home folder (e.g.) and then create the folders needed for seafile.
Data and database will be in local folders using docker volumes with mount binds:
$ mkdir seafile
$ cd seafile
$ mkdir {data, db}
Docker Compose setup
Create a new docker-compose file:
$ nano docker-compose.yml
Copy and paste the content from the example file below.
Value that need to be changed according to your setup:
MYSQL_ROOT_PASSWORDandDB_ROOT_PASSWD(same)SEAFILE_ADMIN_EMAILSEAFILE_ADMIN_PASSWORDSEAFILE_SERVER_HOSTNAME
4. Set up Caddy for seafile
Edit your caddy config file. In Debian this file is in /etc/caddy/. If you don’t know where to find yours,
you can probably look it up with $ ps ax | grep caddy
$ sudo nano /etc/caddy/Caddyfile
Copy and paste the contents from the example Caddyfile below.
Change the domain name to your own.
When you are done, save the file, and reload the caddy service.
In debian:
$ sudo service caddy reload
5. Spin up your seafile docker containers
If you followed the example above, go to
$ cd ~/seafile
To start your containers execute
$ docker-compose up
Now your seafile installation should be reachable under your domain, i.e. https://seafile.YOURSEVER.net
Caddy automatically generates TLS certificates from Let’s Encrypt, https is the default in caddy along with http/2.
If everything has worked and you can login with your admin data from the docker-compose.yml file.
Go back to your terminal and abort the docker-compose process with CTRL-C.
Restart the process in detached mode:
$ docker-compose up -d
6. Make uploads work
To make uploads work for your seafile installation, go to your installation in the browser
i.e. https://seafile.YOURSEVER.net
- Login with admin user
- Click on the avatar in the top right corner
- Select
System-Administration - In the administration window choose
Preferencesfrom the menu on the left - Set up
SERVICE_URLandFILE_SERVER_ROOT: -
Hit the small green checkmark to save your changes per lineSERVICE_URL = https://seafile.YOURSEVER.net FILE_SERVER_ROOT = https://seafile.YOURSEVER.net/seafhttp
Version notes
Versions used for this example are
- Debian 11 Bullseye
- Caddy v2.6.2
- Docker version 24.0.0
- Seafile Server Version: 9.0.10
Some links
seafile.YOURSEVER.net {
reverse_proxy 10.10.10.4:80
}
seafile.YOURSEVER.net/seafhttp* {
uri strip_prefix seafhttp
reverse_proxy 10.10.10.4:8082
}
seafile.YOURSEVER.net/seafdav* {
uri strip_prefix seafdav
reverse_proxy 10.10.10.4:8899
}
version: '2'
services:
db:
image: mariadb:10.5
container_name: seafile-mysql
environment:
- MYSQL_ROOT_PASSWORD=SOMESUPERSECRETPASSWORD # Requested, set the root's password of MySQL service.
- MYSQL_LOG_CONSOLE=true
volumes:
- ./db:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
networks:
default:
ipv4_address: 10.10.10.2
memcached:
image: memcached:1.6
container_name: seafile-memcached
entrypoint: memcached -m 256
networks:
default:
ipv4_address: 10.10.10.3
seafile:
image: seafileltd/seafile-mc:latest
container_name: seafile
# ports: # Commented out since we use our own docker network and don't need these ports on the host directly
# - "80:80"
# - "443:443" # If https is enabled, cancel the comment.
volumes:
- ./data:/shared # Requested, specifies the path to Seafile data persistent store.
environment:
- DB_HOST=db
- DB_ROOT_PASSWD=SOMESUPERSECRETPASSWORD # Requested, the value shuold be root's password of MySQL service.
- TIME_ZONE=Europe/Berlin # Optional, default is UTC. Should be uncomment and set to your local time zone.
- SEAFILE_ADMIN_EMAIL=your@email-address.com # Specifies Seafile admin user, default is 'me@example.com'.
- SEAFILE_ADMIN_PASSWORD=your-user-password # Specifies Seafile admin password, default is 'asecret'.
- SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
- SEAFILE_SERVER_HOSTNAME=seafile.YOURSEVER.net # Specifies your host name if https is enabled.
depends_on:
- db
- memcached
networks:
default:
ipv4_address: 10.10.10.4
networks:
default:
name: seafile_net
external: true
If you encountered an CSFR failed error, you can resolve it using the following method:
nano ./data/seafile/conf/seahub_settings.py
add the following at the end
FILE_SERVER_ROOT = "https://seafile.domain.com/seafhttp"
CSRF_TRUSTED_ORIGINS = ["https://seafile.domain.com"]
CSRF_COOKIE_SECURE = True
ALLOWED_HOSTS = ['.domain.com']
CSRF_COOKIE_SAMESITE = 'Strict'