Seafile is a self-hosted file sync and share platform. Files are organized in libraries that sync to desktop and mobile clients, keep a version history, and can be encrypted on the client so the server never sees their content. In this tutorial you will install Seafile Community Edition on Ubuntu 24.04 with the official Docker Compose files, which include a Caddy proxy that obtains a Let's Encrypt certificate automatically. You will then configure outgoing email, WebDAV and trash retention, and connect a client.
Prerequisites
To follow this guide you need:
- A server running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 2 CPU cores and 2 GB of RAM, plus enough disk for the files you plan to store.
- A non-root user with
sudoprivileges. - Docker Engine and the Docker Compose plugin installed. See How to install Docker on Linux.
- A domain name, referred to as
your_domain(for examplefiles.example.com), with a DNS A record pointing to your server. - Ports 80 and 443 free on the server. The bundled Caddy container binds to them, so do not run another web server such as Nginx or Apache on the same host.
This guide uses the Seafile 12.0 deployment files. If the Seafile admin manual lists a newer major version, use its URLs and follow its upgrade notes; the steps are the same.
Step 1 - Downloading the deployment files
Seafile's Docker deployment consists of an environment file, the Seafile stack (Seafile, MariaDB and Memcached) and the Caddy reverse proxy. Download them into /opt/seafile:
sudo mkdir -p /opt/seafile
cd /opt/seafile
sudo wget -O .env https://manual.seafile.com/12.0/repo/docker/ce/env
sudo wget https://manual.seafile.com/12.0/repo/docker/ce/seafile-server.yml
sudo wget https://manual.seafile.com/12.0/repo/docker/caddy.yml
Confirm the three files are there:
ls -la /opt/seafile
Step 2 - Configuring the environment file
Generate the secrets you need: a MariaDB root password, a password for the seafile database user, and a key that Seafile uses to sign internal tokens (at least 32 characters):
openssl rand -hex 20
openssl rand -hex 20
openssl rand -hex 20
Open the environment file:
sudo nano /opt/seafile/.env
Set the following variables and leave the others at their defaults. COMPOSE_FILE is already set to load both seafile-server.yml and caddy.yml, which is why a plain docker compose command starts the whole stack:
TIME_ZONE=Europe/Madrid
INIT_SEAFILE_MYSQL_ROOT_PASSWORD=your_mariadb_root_password
SEAFILE_MYSQL_DB_PASSWORD=your_seafile_db_password
JWT_PRIVATE_KEY=your_jwt_key
SEAFILE_SERVER_HOSTNAME=your_domain
SEAFILE_SERVER_PROTOCOL=https
INIT_SEAFILE_ADMIN_EMAIL=admin@your_domain
INIT_SEAFILE_ADMIN_PASSWORD=your_admin_password
The INIT_ variables are only read the first time the stack starts, to create the database and the admin account. The data lives under the paths set in SEAFILE_VOLUME (by default /opt/seafile-data) and SEAFILE_MYSQL_VOLUME (by default /opt/seafile-mysql/db).
Restrict the file, since it contains passwords:
sudo chmod 600 /opt/seafile/.env
Step 3 - Starting Seafile
Open the firewall for SSH, HTTP (needed for the Let's Encrypt challenge) and HTTPS:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
Start the stack:
cd /opt/seafile
sudo docker compose up -d
On the first start Seafile creates its three databases and the admin account, and Caddy requests a certificate for your_domain. Follow the Seafile log until initialization is finished, then press Ctrl+C:
sudo docker compose logs -f seafile
Check that all four containers are running:
sudo docker compose ps
NAME IMAGE STATUS
seafile seafileltd/seafile-mc:12.0-... Up 2 minutes
seafile-caddy lucaslorentz/caddy-docker-proxy Up 2 minutes
seafile-memcached memcached:... Up 2 minutes
seafile-mysql mariadb:... Up 2 minutes (healthy)
Verify HTTPS from your own computer:
curl -sI https://your_domain/accounts/login/ | head -n 1
HTTP/2 200
Open https://your_domain in your browser and log in with INIT_SEAFILE_ADMIN_EMAIL and INIT_SEAFILE_ADMIN_PASSWORD. Change the admin password under your avatar > Settings if you reused a password from elsewhere.
Step 4 - Configuring outgoing email and sign-up
Seafile sends email for password resets, share notifications and new users. Its web component (Seahub) is configured in seahub_settings.py, inside the data volume:
sudo nano /opt/seafile-data/seafile/conf/seahub_settings.py
Append your SMTP settings to the end of the file, replacing the placeholders with your mail provider's values:
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.example.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = 'your_smtp_password'
EMAIL_PORT = 587
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
# Only administrators can create accounts
ENABLE_SIGNUP = False
Restart Seafile to load the changes:
cd /opt/seafile
sudo docker compose restart seafile
To test, go to System Admin > Users, add a user, and check that the invitation email arrives.
Step 5 - Enabling WebDAV
WebDAV lets you mount libraries as a network drive on Linux, macOS or Windows, or connect apps that do not have a Seafile client. Open the WebDAV configuration:
sudo nano /opt/seafile-data/seafile/conf/seafdav.conf
Set it to:
[WEBDAV]
enabled = true
port = 8080
share_name = /seafdav
Restart Seafile:
sudo docker compose restart seafile
The Nginx instance inside the Seafile container already forwards /seafdav to the WebDAV server. Test it with a PROPFIND request. A 207 status means authentication worked and the server listed your libraries:
curl -s -o /dev/null -w '%{http_code}\n' -u 'your_email:your_password' -X PROPFIND -H 'Depth: 1' https://your_domain/seafdav/
207
The WebDAV URL for clients is https://your_domain/seafdav. Encrypted libraries are not accessible over WebDAV.
Step 6 - Setting trash retention and quotas
Deleted files go to the library trash and older versions stay in the library history. Both use disk space, so set limits that fit your storage. Open the Seafile server configuration:
sudo nano /opt/seafile-data/seafile/conf/seafile.conf
Add these sections (keep the ones already in the file):
[library_trash]
# Remove files from the trash after 30 days
expire_days = 30
[quota]
# Default quota per user, in GB
default = 50
Restart to apply:
sudo docker compose restart seafile
Library owners can set how long history is kept per library from the library's History Setting menu in the web interface. Administrators can override the quota of individual users in System Admin > Users.
Step 7 - Creating libraries and connecting clients
In the web interface, click New Library. To create an encrypted library, check Encrypt and set a password. Files are encrypted on the client before upload and the password is never sent to the server, so store it safely: the administrator cannot recover it.
Download the desktop client (Windows, macOS, Linux) or the mobile apps from the Seafile download page. In the desktop client:
- Add an account with the server address
https://your_domainand your email and password. - Choose a library in the client and click Sync this library, then pick a local folder.
- Add a file to the local folder and check that it appears in the web interface after a few seconds.
The mobile apps can upload photos from the camera roll automatically; enable it in the app settings and choose the destination library.
Step 8 - Backing up Seafile
A consistent backup needs the databases and the data directory. Dump the databases first, using the root password inside the MariaDB container:
sudo mkdir -p /var/backups/seafile
cd /opt/seafile
sudo docker compose exec -T db sh -c 'mariadb-dump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction --databases ccnet_db seafile_db seahub_db' \
| gzip | sudo tee /var/backups/seafile/seafile-db-$(date +%F).sql.gz > /dev/null
Then copy /opt/seafile-data and /var/backups/seafile to your backup destination, for example with rsync or restic. Take the database dump before copying the data directory, so that the data is never older than the database.
Troubleshooting
The browser shows a certificate error or the site does not load. Check the Caddy log with sudo docker compose logs --tail 50 caddy. The usual causes are a DNS record that does not point to the server yet, or port 80 blocked, which prevents the Let's Encrypt challenge.
"Page unavailable" or a 502 error after start. Seafile is still initializing or failed to reach the database. Check sudo docker compose logs --tail 100 seafile and the Seahub log with sudo tail -n 50 /opt/seafile-data/logs/seahub.log.
Client uploads fail or show a network error, while the web interface works. Make sure SEAFILE_SERVER_HOSTNAME and SEAFILE_SERVER_PROTOCOL in .env match the URL clients use, then recreate the containers with sudo docker compose up -d. Seafile builds the file server URL from these two values, so a mismatch breaks uploads and downloads while page views still work.
Conclusion
Seafile now runs on Ubuntu 24.04 with automatic HTTPS, sends email, serves WebDAV, limits trash and quota usage, and syncs libraries to your devices. As next steps, connect Seafile to your LDAP or OAuth provider for single sign-on, enable two-factor authentication with ENABLE_TWO_FACTOR_AUTH = True in seahub_settings.py, and schedule the database dump and data copy with a cron job and restic.
