Self-Host Seafile: Fast File Sync & E2E Encryption 2026
TL;DR
Seafile (AGPL 3.0, ~12K GitHub stars, Python/C) is the fastest self-hosted file sync platform. Unlike Nextcloud, Seafile is laser-focused on sync performance — it uses a custom object storage format (like Git for files) that makes delta-sync extremely fast. Its killer feature: per-library E2E encryption — each library (folder) can have its own password; the server stores only encrypted blocks and can never read your files. Dropbox charges $9.99/month for 2TB. Seafile self-hosted is free.
Key Takeaways
- Seafile: AGPL 3.0, ~12K stars — fastest sync performance of any self-hosted option
- Per-library encryption: Each library has its own passphrase; server sees only encrypted blocks
- Libraries: Organize files into libraries (like separate drives) with independent sharing
- SeaDoc: Built-in collaborative document editor (Markdown + rich text)
- Delta sync: Only changed file blocks sync — much faster than Nextcloud on large files
- vs Nextcloud: Seafile is faster and has better encryption; Nextcloud has more apps
Seafile vs Nextcloud vs Syncthing
| Feature | Seafile | Nextcloud | Syncthing |
|---|---|---|---|
| License | AGPL 3.0 | AGPL 3.0 | MPL 2.0 |
| Sync speed | Fastest | Medium | Fast |
| E2E encryption | Per-library (free) | Paid add-on | N/A (P2P) |
| File versioning | Yes (trash + history) | Yes | Yes |
| Selective sync | Yes | Yes | Yes |
| Online doc editor | SeaDoc | Collabora/OnlyOffice | No |
| CalDAV/CardDAV | No | Yes | No |
| External storage | S3 compatible | Yes | No |
| RAM usage | ~200MB | ~500MB+ | ~50MB |
| Setup complexity | Medium | Medium | Low |
Part 1: Docker Setup
# docker-compose.yml
services:
db:
image: mariadb:10.11
container_name: seafile_db
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: "${MARIADB_ROOT}"
MARIADB_AUTO_UPGRADE: "true"
volumes:
- db:/var/lib/mysql
memcached:
image: memcached:1.6-alpine
container_name: seafile_memcached
restart: unless-stopped
entrypoint: memcached -m 256
seafile:
image: seafileltd/seafile-mc:latest
container_name: seafile
restart: unless-stopped
ports:
- "8080:80"
volumes:
- seafile_data:/shared
environment:
DB_HOST: db
DB_ROOT_PASSWD: "${MARIADB_ROOT}"
TIME_ZONE: "America/Los_Angeles"
SEAFILE_ADMIN_EMAIL: "${ADMIN_EMAIL}"
SEAFILE_ADMIN_PASSWORD: "${ADMIN_PASSWORD}"
SEAFILE_SERVER_LETSENCRYPT: "false" # We use Caddy
SEAFILE_SERVER_HOSTNAME: "files.yourdomain.com"
depends_on:
- db
- memcached
volumes:
db:
seafile_data:
# .env
MARIADB_ROOT=your-root-password
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=your-admin-password
docker compose up -d
Visit http://your-server:8080 — log in with admin credentials.
Part 2: HTTPS with Caddy
files.yourdomain.com {
reverse_proxy localhost:8080
}
Part 3: Desktop Sync Clients
Install Seafile Desktop (Windows/Mac/Linux)
- Download from seafile.com/download
- Add an account → Server:
https://files.yourdomain.com - Log in → browse your libraries
- Right-click any library → Sync this library → choose local folder
Selective sync
# Sync only specific subfolders:
seaf-cli sync -l LIBRARY_ID -s https://files.yourdomain.com \
-d ~/Seafile/MyLibrary \
-u username@example.com -p password
Part 4: Libraries and Sharing
Seafile uses libraries (like separate volumes):
Create a library
- My Libraries → Create a Library
- Name + optional encryption passphrase
Library types
Personal libraries:
├── "Documents" (unencrypted, synced to desktop)
├── "Private vault" (E2E encrypted with passphrase)
└── "Photos" (unencrypted, backed up from phone)
Shared libraries:
├── "Team Projects" (shared with @coworker, write access)
└── "Public Resources" (shared link, read-only)
Share a library
- Library → Share → enter email or create a share link
- Permission: View only, Upload, Edit
- Password: Optional, for share links
- Expiry: Optional expiry date
Part 5: E2E Encrypted Libraries
The most important Seafile feature:
Create an encrypted library
- My Libraries → Create a Library → check Encrypt
- Enter a passphrase (this is NOT your account password)
- Important: Seafile cannot recover this passphrase — if lost, data is unrecoverable
How it works
Your device (desktop/mobile)
→ Files encrypted with your passphrase (AES-256)
→ Only encrypted blocks sent to server
→ Server stores: [encrypted block 1], [encrypted block 2], [metadata]
→ Server CANNOT read files (no passphrase)
Another device (your laptop)
→ Downloads encrypted blocks
→ Decrypts with passphrase you enter
→ Shows readable files
Decrypt on a new device
# When you sync an encrypted library to a new machine:
# 1. Sync the library
# 2. Desktop app prompts for the passphrase
# 3. Enter passphrase → files decrypted locally
Part 6: File Versioning
Seafile keeps all previous versions:
- File → Version history → see all past versions
- Restore any version with one click
- Configure retention in admin panel:
# Admin panel → Settings → Library file history setting:
KEEP_FILE_REVISIONS = 100 # Keep last 100 versions
FILE_REVISIONS_AUTO_CLEAN = True # Auto-clean old versions after N days
Trash / Recovery
Deleted files go to the library trash (30 days by default):
- Library → Trash → restore or permanently delete
Part 7: SeaDoc (Online Editor)
SeaDoc is Seafile's built-in document editor — think Notion-lite for Seafile:
# Add to docker-compose.yml:
services:
seadoc:
image: seafileltd/sdoc-server:latest
container_name: seadoc
restart: unless-stopped
ports:
- "7070:7070"
volumes:
- seadoc_data:/shared
environment:
SEAFILE_SERVER_HOSTNAME: "files.yourdomain.com"
DB_HOST: db
DB_ROOT_PASSWD: "${MARIADB_ROOT}"
TIME_ZONE: "America/Los_Angeles"
depends_on:
- db
Click any .sdoc file to edit collaboratively in real-time.
Part 8: REST API
# Get auth token:
TOKEN=$(curl -s -d "username=${EMAIL}&password=${PASS}" \
https://files.yourdomain.com/api2/auth-token/ | jq -r .token)
# List libraries:
curl https://files.yourdomain.com/api2/repos/ \
-H "Authorization: Token $TOKEN" | jq '.[].name'
# Upload a file:
curl -X POST "https://files.yourdomain.com/api2/repos/${REPO_ID}/upload-link/" \
-H "Authorization: Token $TOKEN"
# Returns upload link, then POST file to that link
# Download a file:
DOWNLOAD_LINK=$(curl "https://files.yourdomain.com/api2/repos/${REPO_ID}/file/?p=/path/to/file.txt" \
-H "Authorization: Token $TOKEN" | jq -r .)
curl "$DOWNLOAD_LINK" -o file.txt
# Create a share link:
curl -X PUT "https://files.yourdomain.com/api2/repos/${REPO_ID}/file/shared-link/" \
-H "Authorization: Token $TOKEN" \
-d "p=/document.pdf&share_type=d"
Maintenance
# Update Seafile:
docker compose pull
docker compose up -d
# Backup:
# Database:
docker exec seafile_db mysqldump --all-databases -uroot -p"${MARIADB_ROOT}" \
| gzip > seafile-db-$(date +%Y%m%d).sql.gz
# Data (file blocks + config):
tar -czf seafile-data-$(date +%Y%m%d).tar.gz \
$(docker volume inspect seafile_seafile_data --format '{{.Mountpoint}}')
# Check storage usage:
docker exec seafile /opt/seafile/seafile-server-latest/seaf-gc.sh
# Logs:
docker compose logs -f seafile
See all open source cloud storage tools at OSSAlt.com/categories/storage.