Skip to main content

Self-Host Seafile: Fast File Sync & E2E Encryption 2026

·OSSAlt Team
seafiledropboxfile-syncencryptionself-hostingdocker2026

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

FeatureSeafileNextcloudSyncthing
LicenseAGPL 3.0AGPL 3.0MPL 2.0
Sync speedFastestMediumFast
E2E encryptionPer-library (free)Paid add-onN/A (P2P)
File versioningYes (trash + history)YesYes
Selective syncYesYesYes
Online doc editorSeaDocCollabora/OnlyOfficeNo
CalDAV/CardDAVNoYesNo
External storageS3 compatibleYesNo
RAM usage~200MB~500MB+~50MB
Setup complexityMediumMediumLow

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)

  1. Download from seafile.com/download
  2. Add an account → Server: https://files.yourdomain.com
  3. Log in → browse your libraries
  4. 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

  1. My Libraries → Create a Library
  2. 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

  1. Library → Share → enter email or create a share link
  2. Permission: View only, Upload, Edit
  3. Password: Optional, for share links
  4. Expiry: Optional expiry date

Part 5: E2E Encrypted Libraries

The most important Seafile feature:

Create an encrypted library

  1. My Libraries → Create a Library → check Encrypt
  2. Enter a passphrase (this is NOT your account password)
  3. 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:

  1. File → Version history → see all past versions
  2. Restore any version with one click
  3. 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.

Comments