TL;DR
Official Docker image (Community Edition):
| |
Binary install, or a container with the manual sequence:
| |
On Kubernetes, the same inside the pod: kubectl -n seafile exec -it deploy/seafile -- bash and the sequence above (or /scripts/gc.sh if it is the official image).
Before anything else: System Admin → Libraries → Trash → clean. A library sitting in the trash keeps all of its blocks and the GC will not touch it.
Why the disk does not shrink by itself
Seafile stores files chunked into content-addressed blocks under seafile-data/storage/ (blocks/, fs/, commits/). Deleting a file or a library only writes a new commit; the blocks stay because the library’s history still references them, and because another library or an older version might use them. The only thing that removes them is seaf-gc, which walks the live commits and deletes everything nobody references anymore.
Two things decide what “nobody” means:
- The library trash in the admin panel: a library deleted by a user is not removed, it is moved there. Until you clean it, its blocks count as alive.
- Each library’s history (History settings: days to keep). The GC honors that window; with unlimited history, blocks from old versions are never freed.
Requirements
- Community Edition: Seafile stopped. Blocks written while the GC runs could be deleted by mistake. The official image’s
/scripts/gc.shstops and starts it for you; by hand,seafile.sh stopbefore andseafile.sh startafter. Pro has online GC. - Maintenance window. Runtime grows with storage size; on big installs it is hours.
- Backup or snapshot of
seafile-data(on ZFS, azfs snapshotis instant). It is the first time something will actually delete blocks.
seaf-gc.sh options
| Option | What it does |
|---|---|
--dry-run | Counts what would be deleted and deletes nothing. Always start here |
-r | Only blocks from deleted libraries (the ones already purged from the trash), without checking history. The fastest for “I deleted a 500 GB library” |
--rm-fs | Also deletes orphaned fs objects. Buggy before CE 11.0.7 / Pro 10.0.15; upgrade before using it |
-t N | Threads. Only helps with object backends (S3, etc.); with a local filesystem leave it at 1 |
--id-prefix ab | Only libraries whose ID starts with that prefix (to split a long pass) |
<id> [<id>…] | Only those libraries |
Single-library dry run:
| |
Full procedure
- Admin panel → Libraries → Trash → clean (or Clean per library). Without this step the GC reports zero blocks and you wonder why.
- Review the history of the big libraries (History settings); if they keep everything forever, decide on a number of days.
- Snapshot or backup of
seafile-data. docker exec seafile /scripts/gc.sh, or the manual sequence with--dry-runfirst. The output ends with the per-library block summary.- Check:
du -sh /opt/seafile-data/seafile/storage/blocksanddf -h.
To avoid doing it by hand, a weekly overnight cron with the same docker exec is enough on CE.
Traps
- “GC frees nothing”: trash not emptied, unlimited history, or blocks held by filesystem snapshots (on ZFS,
zfs list -t snapshotand itsUSED). - Never with Seafile up on CE. If the container runs
seafile-serveras its main process,seafile.sh stopinside can take the container down; with the official image use/scripts/gc.sh, which accounts for it. --rm-fson old versions can delete objects that are in use; only from CE 11.0.7.- Nginx in front and clients showing Server error when syncing after the GC: it is usually
client_max_body_sizetoo low, not the GC; set it to0in Seafile’sserverblock. - Encrypted libraries are collected the same way; the GC does not need the password.
Reference: Seafile GC in the admin manual.