Seafile
Self-hosted file sync and share platform with document editing (SeaDoc).
- URL:
https://docs.alogins.net - Admin:
https://docs.alogins.net/sys/info/ - Data:
/mnt/misc/seafile/ - Port:
127.0.0.1:8078(proxied via Caddy)
Setup
cd ~/agap_git/seafile
cp .env.example .env # fill in credentials from Vaultwarden
docker compose up -d
Credentials stored in Vaultwarden AI collection:
| Item name | Description |
|---|---|
SEAFILE_MYSQL_DB_PASSWORD |
MariaDB seafile user password |
SEAFILE_INIT_MYSQL_ROOT_PASSWORD |
MariaDB root password (first-run only) |
SEAFILE_INIT_ADMIN_EMAIL |
Initial admin email |
SEAFILE_INIT_ADMIN_PASSWORD |
Initial admin password |
SEAFILE_REDIS_PASSWORD |
Redis password |
SEAFILE_JWT_PRIVATE_KEY |
JWT signing key |
Stack
| Container | Image | Role |
|---|---|---|
seafile |
seafileltd/seafile-mc:13.0 |
Main app (port 8078 on host) |
seadoc |
seafileltd/sdoc-server:2.0 |
Document editing |
seafile-mysql |
mariadb:10.11 |
Database |
seafile-redis |
redis |
Cache |
seafile-caddy |
lucaslorentz/caddy-docker-proxy |
Internal proxy (port 8077, unused) |
WebDAV
WebDAV is enabled at https://docs.alogins.net/seafdav/. Each library appears as a folder.
Mount on the host:
sudo mkdir -p /mnt/seafile
sudo mount -t davfs https://docs.alogins.net/seafdav/ /mnt/seafile -o uid=1000,gid=1000
# username: allogn@gmail.com, password: Seafile admin password
Note: add 127.0.0.1 docs.alogins.net to /etc/hosts — the public IP is unreachable from the host itself (hairpin NAT).
Permanent mount (fstab)
Install davfs2 and allow non-root mounts:
sudo apt install davfs2
sudo usermod -aG davfs2 alvis
Store credentials in /etc/davfs2/secrets:
https://docs.alogins.net/seafdav/ allogn@gmail.com <password>
Add to /etc/fstab:
https://docs.alogins.net/seafdav/ /mnt/seafile davfs uid=1000,gid=1000,_netdev 0 0
Mount:
sudo mkdir -p /mnt/seafile
sudo mount /mnt/seafile
Manual mount
sudo mount -t davfs https://docs.alogins.net/seafdav/ /mnt/seafile -o uid=1000,gid=1000
sudo umount /mnt/seafile
Enabled in seafdav.conf (inside container at /shared/seafile/conf/):
[WEBDAV]
enabled = true
port = 8080
share_name = /seafdav
Backup
Script: ~/agap_git/seafile/backup.sh
Destination: /mnt/backups/seafile/<timestamp>/
Schedule: every 3 days at 2:00 AM (root crontab)
Retention: last 5 backups
Backs up:
- MySQL dumps of
ccnet_db,seafile_db,seahub_dbviadocker exec seafile-mysql mysqldump - All seafile data via
rsync(excludes mysql and caddy dirs)
Zabbix monitoring: trapper item seafile.backup.ts (id 70369) on host AgapHost. Trigger fires if no backup in 4 days.
OnlyOffice Integration
Online editing of .docx, .xlsx, .pptx via OnlyOffice Document Server.
- URL:
https://office.alogins.net - Port:
127.0.0.1:6233(proxied via Caddy) - JWT secret: stored in Vaultwarden as
ONLYOFFICE_JWT_SECRET
seahub_settings.py (inside container at /shared/seafile/conf/):
ENABLE_ONLYOFFICE = True
ONLYOFFICE_APIJS_URL = 'https://office.alogins.net/web-apps/apps/api/documents/api.js'
ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods', 'csv', 'ppsx', 'pps')
ONLYOFFICE_EDIT_FILE_EXTENSION = ('docx', 'pptx', 'xlsx')
ONLYOFFICE_JWT_SECRET = '<from Vaultwarden>'
Hairpin NAT fix: hairpin routing affects both directions of the integration:
onlyoffice.yml→docs.alogins.net:host-gateway(OnlyOffice fetches files from Seafile and posts save callbacks).seafile-server.yml→office.alogins.net:host-gateway(Seahub downloads the saved file from OnlyOffice's cache after a save callback).
Without both, save callbacks time out (~134s), OnlyOffice retries, hits the backoff limit, and drops the edit into forgotten/ — the file on disk stays at the old version and the editor shows "the file version has been changed" on reopen.
Troubleshooting
"Loading spreadsheet" hangs forever
OnlyOffice editor assets (e.g. fonts_ie.js) served over HTTP/3 can stall on distant/lossy connections — Caddy aborts with writing: timeout: no recent network activity. Fix: disable HTTP/3 globally in /etc/caddy/Caddyfile:
{
servers {
protocols h1 h2
}
}
Browsers cache the Alt-Svc: h3 hint for 30 days, so after reloading Caddy fully quit the browser (or test in a private window) to drop the cached hint.
"The file version has been changed" loop on reopen
Caused by Seahub's save callback timing out (hairpin NAT, see above). Symptoms in logs:
seahub.log:ConnectTimeoutError: Connection to office.alogins.net timed outseahub.access.log:POST /onlyoffice/editor-callback/ ... 500 285 ... 134.xxx(seconds)onlyofficecontainer:commandSfcCallback backoff limit exceeded→storeForgotten- Files accumulate in
/var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten/<doc_key>/output.xlsx
After adding the office.alogins.net:host-gateway extra_host and recreating the seafile container, clear the stuck state:
# 1. Inspect or recover any forgotten edits first
docker exec seafile-onlyoffice ls /var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten/
# 2. Wipe OnlyOffice's forgotten cache
docker exec seafile-onlyoffice sh -c \
'rm -rf /var/lib/onlyoffice/documentserver/App_Data/cache/files/forgotten/*'
# 3. Wipe Seafile's cached doc_keys so fresh sessions generate new ones
PW=$(grep INIT_SEAFILE_MYSQL_ROOT_PASSWORD ~/agap_git/seafile/.env | cut -d= -f2)
docker exec seafile-mysql mysql -uroot -p"$PW" -e \
'DELETE FROM onlyoffice_onlyofficedockey;' seahub_db
Seafile stores the (repo_id, file_path) → doc_key mapping in seahub_db.onlyoffice_onlyofficedockey.
OnlyOffice degraded after long uptime
After weeks without restart, docservice leaks AMQP heartbeats ([AMQP] conn error Error: Heartbeat timeout in /var/log/onlyoffice/documentserver/docservice/out.log) and Socket.IO sessions fail (io.connection_error ... Transport unknown). Restart clears it:
cd ~/agap_git/seafile && docker compose restart onlyoffice
Notes
SEAFILE_SERVER_PROTOCOL=httpsrequired — setting it tohttpcauses CSRF errors when accessed via HTTPSTIME_ZONEmust be a valid tz name (e.g.Asia/Dubai) —Etc/UTC+4is invalid and causes container crash.envis gitignored — credentials stored in Vaultwarden only- Caddy proxies directly to
seafilecontainer on port 8078, bypassing the internal seafile-caddy