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