Seafile Pro
Seafile Pro is the Blueprint’s file sync and sharing platform — private cloud storage with browser-based Office editing (OnlyOffice), collaborative document editing (SeaDoc), full-text search (SeaSearch), and antivirus scanning (ClamAV). All ten services deploy as a single Compose stack.
Written against 13.0.21 · no verification recorded against that version
Not exercised: backup and restore. Three databases, the block store and the search index have to be recovered in order, and none of it has been rehearsed.
Needs: Traefik running, a hostname, a Seafile Pro commercial license, and an external OnlyOffice instance for .docx/.xlsx/.pptx editing (optional — all other features work without it).
Installation
Section titled “Installation”From apps/seafile-pro/:
-
Terminal window cp .env.example .env -
Set required values in
.env:APP_TRAEFIK_HOST=files.example.comSEAFILE_ADMIN_EMAIL=admin@example.comTZ=Europe/Vienna -
Generate passwords and the JWT key:
Terminal window sed -i "s|^INIT_SEAFILE_MYSQL_ROOT_PASSWORD=.*|INIT_SEAFILE_MYSQL_ROOT_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')|" .envsed -i "s|^SEAFILE_MYSQL_DB_PASSWORD=.*|SEAFILE_MYSQL_DB_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')|" .envsed -i "s|^INIT_SEAFILE_ADMIN_PASSWORD=.*|INIT_SEAFILE_ADMIN_PASSWORD=$(openssl rand -base64 32 | tr -d '\n')|" .envsed -i "s|^JWT_PRIVATE_KEY=.*|JWT_PRIVATE_KEY=$(openssl rand -base64 48 | tr -d '\n')|" .envsed -i "s|^REDIS_PASSWORD=.*|REDIS_PASSWORD=$(openssl rand -hex 32)|" .env -
If using OnlyOffice, set the hostname and copy the JWT secret — it must match the OnlyOffice server exactly:
ONLYOFFICE_HOST=office.example.comTerminal window # sed -i "s|^ONLYOFFICE_JWT_SECRET=.*|ONLYOFFICE_JWT_SECRET=<value-from-core/onlyoffice>|" .env -
Pull images:
Terminal window docker compose pull -
Start the stack:
Terminal window docker compose up -d -
Wait for all containers to be healthy — first boot initialises the databases and takes roughly three minutes:
Terminal window docker compose ps -
Required: restart the app container once to inject Blueprint configs into Seafile’s settings files. This step only needs to run once — a marker prevents it from repeating on subsequent restarts:
Terminal window docker compose restart app -
Build the initial full-text search index:
Terminal window docker exec seafile-pro-app /opt/seafile/seafile-server-latest/pro/pro.py search --update
Verify
Section titled “Verify”docker compose ps # all ten containers up; app, db, redis, clamav should show healthyConfirm the config injection from step 8 ran:
docker exec seafile-pro-app grep "Blueprint" /shared/seafile/conf/seahub_settings.pydocker exec seafile-pro-app grep "SEASEARCH" /shared/seafile/conf/seafevents.confdocker exec seafile-pro-app grep "virus_scan" /shared/seafile/conf/seafile.confEach command should return a matching line. No output means the injection step was skipped — run docker compose restart app and recheck.
Confirm the notification server is reachable:
curl -s https://your-domain/notification/ping # {"ret": "pong"}Test antivirus:
docker exec seafile-pro-app bash -c "curl -s https://secure.eicar.org/eicar.com.txt | clamdscan -"# Expected: stream: Eicar-Test-Signature FOUNDThen in the browser, confirm each service works:
- Log in with the admin account.
- Upload a file and download it back.
- Create and edit a Markdown (
.md) file. - Open a
.docxin the OnlyOffice editor (requires OnlyOffice configured). - Create a
.sdocfile and open it in SeaDoc. - Search for a word from an uploaded file — SeaSearch should return it.
OnlyOffice
Section titled “OnlyOffice”OnlyOffice embeds a browser-based Office editor into Seafile. It runs as a separate server — either another Blueprint stack or a different machine — and both sides share the same JWT secret.
Server-to-server path: OnlyOffice needs a direct network route to Seafile’s configured hostname to fetch files and save edits back. That path can be a public internet connection or a private route such as Tailscale. If DNS for the Seafile hostname resolves to a Tailscale address on the OnlyOffice host, it will use that path automatically — no additional configuration is needed on the OnlyOffice side for the network path itself.
Allowed origins: On the OnlyOffice server, add the Seafile origin to ONLYOFFICE_ALLOWED_ORIGINS in its .env so browsers are permitted to embed the editor in an iframe. In the Blueprint’s core/onlyoffice stack this value is embedded in a Traefik label — changing it takes effect only after recreating the container, not after a plain restart:
# On the OnlyOffice server — restart is NOT enough:docker compose up -d --force-recreateGoing further
Section titled “Going further”SMTP is optional but required for password reset emails, share invitations, and file change notifications. Set the SMTP variables in .env:
SEAFILE_SMTP_HOST=smtp.example.comSEAFILE_SMTP_PORT=587SEAFILE_SMTP_USER=user@example.comSEAFILE_SMTP_FROM=seafile@example.comSEAFILE_SMTP_USE_TLS=trueSEAFILE_SMTP_PASSWORD=your-smtp-passwordThen recreate the app so it picks up the new values — docker compose restart keeps the environment the container was created with, so a changed
.env would have no effect:
docker compose up -d appThe default APP_TRAEFIK_ACCESS=acc-public removes Traefik’s source-IP allowlist. Whether the service is actually reachable from the public internet depends on your DNS records, routing, and upstream firewall — the acc-public middleware setting does not control any of that.
Setting APP_TRAEFIK_ACCESS=acc-tailscale enforces a source-IP allowlist for Tailscale addresses, restricting access to clients connected to the same Tailnet. Server-to-server integrations (OnlyOffice, notifications) must also reach Seafile via Tailscale for this to apply to them.
ClamAV is included in the default COMPOSE_FILE and configured automatically when the Blueprint config injection runs (step 8 of the installation). Uploaded files are scanned on write.
To verify ClamAV is active:
docker exec seafile-pro-app bash -c "curl -s https://secure.eicar.org/eicar.com.txt | clamdscan -"# Expected: stream: Eicar-Test-Signature FOUNDA startup log warning about the clamd socket (Clamd was NOT notified) is expected during container initialisation — it is a timing race and does not affect scanning once the container is up.
SeaSearch is the default full-text search backend. It is lightweight and configured automatically by the config injection step — no manual setup required.
Elasticsearch is available in the repository as a reference compose file (elasticsearch.yml) but is not active by default and not included in COMPOSE_FILE. Do not add it alongside SeaSearch — both cannot run simultaneously.
Trigger a manual index rebuild after bulk uploads or a first install:
docker exec seafile-pro-app /opt/seafile/seafile-server-latest/pro/pro.py search --updateBackup
Section titled “Backup”Backup and restore covers the host side — Borgmatic, the repository, the schedule and the database hooks. What this stack contributes:
volumes/seafile-data/— all user files and library datavolumes/mysql/— all three databases (Seafile, Seahub, Ccnet)volumes/seadoc-data/— collaborative document state- The
.envfile and any secrets
Updates
Section titled “Updates”-
Read the Seafile Pro release notes and the Docker upgrade guide for breaking changes.
-
Back up all volumes before touching the stack.
-
Update image tags in
.env—APP_TAGfor the main server, and the tags for any component services that changed. -
Pull and recreate:
Terminal window docker compose pulldocker compose up -d -
Watch app logs for any database migration output:
Terminal window docker compose logs -f app -
Verify login, file access, editing, and search after the update.
Troubleshooting
Section titled “Troubleshooting”Repository files
Section titled “Repository files”apps/seafile-pro/README.md— full setup, config injection details, and verification commandsapps/seafile-pro/UPSTREAM.md— upstream notes, known limitations, troubleshooting table, and upgrade checklistapps/seafile-pro/.env.example— all configurable variables with inline comments
© 2026 SecDockBlueCode Apache-2.0Site content licence not yet decided