seafile/implementation_plan.md

188 lines
9.5 KiB
Markdown

# 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.