seafile/implementation_plan.md

9.5 KiB

Implementation Plan

[Overview] Package Seafile Server Core (seafile-server) and Seahub (Django web UI) into a single-container image suitable for TrueNAS SCALE Dragonfish Custom App deployment.

This implementation builds a single container that runs all required services for a functional Seafile deployment: MariaDB (in-container as per decision), Redis, Seafile file server (Go), Seafile core daemons, and Seahub behind an in-container Nginx reverse proxy. The container exposes HTTP/HTTPS and uses a single persistent volume at /data to store configuration, databases, media, and logs. The plan prioritizes reliability and repeatability on TrueNAS SCALE, using official Seafile release artifacts by default while documenting an alternative-from-source build path for the provided repositories.

Key runtime components:

  • Nginx reverse proxy (ports 80/443) → proxies to internal gunicorn (Seahub) and fileserver
  • gunicorn serving Seahub (Django) on 127.0.0.1:8000
  • Seafile "fileserver" (Go) on 127.0.0.1:8082
  • Seafile core services (seaf-server and related daemons)
  • MariaDB (in-container) for metadata
  • Redis (in-container) for caching/pubsub
  • One persistent mount at /data containing conf, databases, media, and logs

Assumptions:

  • Database: In-container MariaDB (user confirmed).
  • Web: In-container Nginx reverse proxy (for TLS termination and path routing).
  • Redis: In-container Redis (to keep single-container constraint).
  • Persistent storage: Single mount /data (with subdirectories).
  • Build source: Default to official Seafile release artifacts for server daemons; include an optional from-source path for the provided seafile-server and seahub repositories.

[Types]
Configuration and environment are expressed via environment variables and YAML/INI-like files written at container start.

Type definitions and configuration contracts:

  • EnvConfig (environment variables):
    • SEAFILE_SERVER_HOSTNAME: string (required), hostname (e.g., files.example.com)
    • SEAFILE_SERVER_URL: string (required), public base URL (e.g., https://files.example.com)
    • ADMIN_EMAIL: string (optional, used at first-run to create admin)
    • ADMIN_PASSWORD: string (optional, used at first-run)
    • DB_ROOT_PASSWORD: string (required for MariaDB bootstrap)
    • DB_NAME: string, default "seafile"
    • DB_USER: string, default "seafile"
    • DB_PASSWORD: string, required
    • REDIS_URL: string, default "redis://127.0.0.1:6379/0"
    • TIMEZONE: string, default "UTC"
    • NGINX_MAX_BODY: string, default "50m"
    • SEAFILE_DATA_DIR: string, default "/data/seafile-data"
    • SEAFILE_CONF_DIR: string, default "/data/conf"
    • SEAHUB_MEDIA_DIR: string, default "/data/seahub-media"
    • LOG_DIR: string, default "/data/logs"
    • SSL_ENABLE: bool, default "false" (TrueNAS may handle TLS; if true, place certs at /data/ssl)
  • FileLayout:
    • /data/conf/: central Seafile/Seahub config (ccnet/seafile.conf, seahub_settings.py)
    • /data/seafile-data/: seafile data store
    • /data/db/: MariaDB datadir
    • /data/redis/: Redis data (if persistence desired)
    • /data/seahub-media/: uploads and media
    • /data/logs/: logs (nginx, seahub, seafile, supervisord)
    • /data/ssl/: TLS certs (optional)
  • NginxConfig:
    • server_name: from SEAFILE_SERVER_HOSTNAME
    • upstreams:
      • seahub: 127.0.0.1:8000
      • fileserver: 127.0.0.1:8082
    • routes:
      • /: proxy to seahub, static caching rules
      • /seafhttp: proxy_pass to fileserver, client_max_body_size NGINX_MAX_BODY
      • /media: alias to /opt/seafile/seahub/media (static), or to collected static path
  • DBConfig:
    • Databases: seafile [and related], initialized via official seafile init scripts or seafile-admin tooling from release package
    • User and grants as per Seafile docs

[Files] Single Dockerfile-based image and runtime scripts; all persistent state under /data.

New files to be created:

  • Dockerfile
    • Multi-stage (optional) to fetch official Seafile release tarball and build Go fileserver if not bundled
    • Installs: nginx, supervisor, mariadb-server, redis-server, python3, python3-venv, pip, required OS libs, curl, tzdata
    • Sets up non-root user (e.g., seafile) and folders under /opt/seafile
  • docker/entrypoint.sh
    • Idempotent bootstrap: initialize /data layout, MariaDB, Redis, Seafile configs, Django SECRET_KEY, admin user
    • Runs database migrations and static collection for Seahub
    • Starts supervisord
  • docker/supervisord.conf
    • Programs:
      • mariadbd
      • redis-server
      • seafile core (seaf-server and any required service supervisors)
      • fileserver (Go binary)
      • gunicorn (Seahub)
      • nginx
  • docker/nginx.conf
    • Reverse proxy configuration and size limits
  • docker/gunicorn.conf.py
    • Workers, timeouts, bind address 127.0.0.1:8000
  • docker/init_db.sh
    • Initializes MariaDB root password, creates seafile DB/user
  • docker/healthcheck.sh
    • Checks HTTP 200 on /ping or /accounts/login/ and fileserver /ping if available
  • docker/seahub_settings.py.template
    • Generates seahub_settings.py under /data/conf
  • docker/requirements-override.txt (optional)
    • Pin/override Python deps if necessary for release compatibility

Existing files to be modified:

  • None inside provided source trees; implementation uses release artifacts and runtime-generated config under /data.

Files to be deleted or moved:

  • None.

Configuration file updates:

  • /data/conf/seahub_settings.py generated with database, cache (Redis), ALLOWED_HOSTS, SITE_BASE_URL, media/static paths, SECRET_KEY
  • /data/conf/seafile.conf generated with service URLs and seafile-data path
  • Nginx server_name and upstreams from env vars

[Functions] Shell-level entrypoint functions and service supervisors are introduced.

New functions (shell) with purpose:

  • entrypoint.sh:init_layout()
    • Create /data subdirectories; set permissions for seafile/nginx/mysql/redis users.
  • entrypoint.sh:init_mariadb()
    • Initialize mariadb datadir if empty; secure install; create seafile DB/user with grants.
  • entrypoint.sh:init_redis()
    • Write minimal redis.conf (dir /data/redis, protected-mode yes).
  • entrypoint.sh:init_seafile()
    • If /data/conf empty, unpack official seafile-server release, run init scripts to generate seafile.conf, seahub_settings.py template; place into /data/conf; create seafile-data dir.
  • entrypoint.sh:init_seahub()
    • Create Python venv, pip install -r requirements; generate SECRET_KEY if missing; run Django collectstatic; perform DB migrations; optionally create admin user if ADMIN_EMAIL and ADMIN_PASSWORD present.
  • entrypoint.sh:configure_nginx()
    • Render nginx.conf using env vars; enable gzip, client_max_body_size, proxy headers, X-Accel config if needed.
  • entrypoint.sh:wait_for_services()
    • Wait for MariaDB and Redis sockets ready.
  • entrypoint.sh:run_supervisord()
    • Start all services via supervisord.

Modified functions (N/A in existing codebase; these are new runtime scripts).

Removed functions:

  • N/A.

[Classes] No new application-level classes; infra relies on supervisord processes and Nginx. Django app (Seahub) remains unmodified.

New classes:

  • N/A.

Modified classes:

  • N/A.

Removed classes:

  • N/A.

[Dependencies] Container-level OS and language dependencies and Seafile release artifacts.

New packages (apt):

  • nginx, supervisor, mariadb-server, redis-server
  • python3, python3-venv, python3-pip
  • curl, ca-certificates, tzdata
  • build deps only if compiling from source variant: build-essential, autoconf, automake, libtool, pkg-config, libglib2.0-dev, libevent-dev, libjansson-dev, uuid-dev, libsqlite3-dev, libssl-dev, zlib1g-dev, libmysqlclient-dev, libarchive-dev, libcurl4-openssl-dev, libhiredis-dev, libjwt-dev, libargon2-dev, golang

Python packages (from seahub/requirements.txt, vetted for release compatibility):

  • Django 5.2., DRF 3.16., gunicorn 23., mysqlclient 2.2., redis 6.2.*, and listed dependencies.

Integration requirements:

  • Official Seafile server release tarball (server core + scripts) matching Seahub version
  • For from-source variant, align seafile-server and seahub versions and run autogen/configure/make install flow plus Go fileserver build.

[Testing] Container functional tests via healthchecks and basic web/API flow.

Test requirements and validation strategies:

  • Healthcheck: curl http://127.0.0.1/accounts/login/ returns 200 after startup
  • Fileserver: curl http://127.0.0.1/seafhttp/ returns expected status or ping endpoint
  • Admin creation: login with ADMIN_EMAIL/ADMIN_PASSWORD succeeds
  • Upload flow: create test library, upload a small file via UI; verify in seafile-data
  • Persistence: stop/start container; verify data preserved at /data
  • Logs: verify absence of critical errors in /data/logs/*

[Implementation Order] Implement in layers to minimize complexity: image base, config generation, service orchestration, then polish and tests.

  1. Dockerfile: base image, OS deps, users, directories, copy scripts/templates.
  2. Download and lay down official Seafile release artifacts in /opt/seafile (or document from-source alternative).
  3. Add Python venv creation and pip install for Seahub requirements.
  4. Add Nginx, gunicorn, Redis, MariaDB, and supervisord configuration files.
  5. Implement entrypoint.sh to initialize /data, DBs, configs, static, migrations, admin user.
  6. Wire supervisord programs for services; ensure start order and restart policies.
  7. Add healthcheck.sh and Docker HEALTHCHECK.
  8. Expose ports 80/443; document TrueNAS mount /data and required env vars.
  9. Smoke test locally with docker run and validate UI, uploads, persistence.
  10. Document alternative from-source build path (autotools + Go) for provided repositories if explicit source-build is later required.