seafile
Seafile Community Edition 13: file sync and share with libraries, web, desktop and mobile clients. Based on the official 13.0 Docker compose, without its bundled Caddy; the platform proxy terminates TLS.
Four containers: seafile (Seahub web UI and file server), notification
(real-time change notifications over WebSocket), db (MariaDB) and cache
(Redis).
Setup
-
Set
SEAFILE_SERVER_HOSTNAME,JWT_PRIVATE_KEY,INIT_SEAFILE_ADMIN_EMAIL,INIT_SEAFILE_ADMIN_PASSWORD,DB_PASSWORDandDB_ROOT_PASSWORD. -
Map the domains, both on the same host:
Container Domain Port seafilehttps://seafile.example.com80notificationhttps://seafile.example.com/notification8083Keep the app's strip-prefix setting on (the default), so the notification server receives
/rather than/notification. -
Deploy. The first start creates the databases and the admin account; log in with
INIT_SEAFILE_ADMIN_EMAIL/INIT_SEAFILE_ADMIN_PASSWORD.
Health check: curl -f http://localhost:80 inside seafile, from the official
compose. Its start period is two minutes instead of the official ten seconds:
the first start creates the databases before Seahub answers, and
notification waits for seafile to be healthy.
Environment
| Variable | Default | Purpose |
|---|---|---|
SEAFILE_SERVER_HOSTNAME |
— | Public hostname, without scheme; also builds the notification URL |
JWT_PRIVATE_KEY |
— | Shared secret between seafile and notification, 32+ characters |
INIT_SEAFILE_ADMIN_EMAIL / INIT_SEAFILE_ADMIN_PASSWORD |
— | Admin account, first start only |
DB_PASSWORD |
— | Password of the seafile MariaDB user |
DB_ROOT_PASSWORD |
— | MariaDB root password, used by the first start to create the user and databases |
TIME_ZONE |
Etc/UTC |
Server time zone |
SEAFILE_SERVER_PROTOCOL is fixed to https: TLS ends at the proxy, but the
generated links, CSRF origins and notification URL must use the public scheme.
The INIT_* variables and DB_ROOT_PASSWORD take effect only on the first
start. Changing them later does not change the admin account or the database
passwords.
Logs go to stdout (SEAFILE_LOG_TO_STDOUT=true) so they show in the
platform's log view instead of only under /shared/seafile/logs.
Storage
| Volume | Mount | Holds |
|---|---|---|
seafile-data |
/shared |
Libraries, config, logs |
db-data |
/var/lib/mysql |
The ccnet, seafile and seahub databases |
cache-data |
/data |
Redis cache |
notification has no volume: it reads its settings from the environment and,
with SEAFILE_LOG_TO_STDOUT=true, writes no log file, so the log mount of the
official compose is not needed.
The redis image declares /data a volume, so without a named one Docker
creates an anonymous volume on every recreate.
Left out
- SeaDoc (
ENABLE_SEADOC=false). It needs/sdoc-server/with the prefix stripped and/socket.io/with it kept, on the same host. The proxy's strip-prefix setting applies to the whole app, so both cannot be routed at once. - Thumbnail server. It needs
/thumbnail/unstripped and/thumbnail/pingrewritten to/ping, the same conflict. Without it, Seahub generates thumbnails itself. - SeaSearch, Seafile AI, metadata server. Not needed for file sync; SeaSearch publishes no arm64 image.
- Redis password. The official compose passes an empty one by default; Redis is reachable only on the app's internal network.
Images
seafileltd/seafile-mc:13.0-latest and
seafileltd/notification-server:13.0-latest track the 13.0 line. Seafile
publishes no :13 tag, latest has not moved since 2025, and 14 is still a
testing release. A Seafile major upgrade runs database migrations; back up
both volumes first.
mariadb:10.11 is the version the official 13.0 compose pins, and the tag
follows its patch releases. MARIADB_AUTO_UPGRADE=1 (from the official compose) runs
mariadb-upgrade after a minor update. A MariaDB data directory cannot move
back to an older major.
redis:8 is the major the official compose's unpinned redis resolves to
today; the tag keeps it there instead of following a future major with no
review. Redis holds only cache, so a version change loses nothing.