- Enable gevent cooperative multitasking in all uWSGI worker configs
(gevent-early-monkey-patch + import dispatcharr.gevent_patch)
- Rewrite WebSocket group sends to bypass asyncio in gevent workers:
_gevent_ws_send() replicates the channels_redis 4.x wire format
directly via synchronous Redis so send_websocket_update() and
_send_async() no longer fail silently after epoll is patched out
- Fix PostgreSQL connection exhaustion: CONN_MAX_AGE=0 + explicit
close_old_connections() in stream manager and cleanup watchdog loops
- Fix stream proxy race: register client before the connect-wait loop
so the cleanup watchdog never sees zero clients on a live channel
- Channel list/logo/profile queryset optimisations: conditional DISTINCT,
EXISTS semi-joins for filter-options, channel_count annotation to
eliminate N+1 in LogoSerializer, prefetched memberships in
ChannelProfileSerializer
- JsonResponse for channel ID list and summary endpoints
- Explicitly stop uwsgi, celery, daphne, and redis-server on SIGTERM;
these are spawned as uwsgi attach-daemons and were not tracked in
pids[], causing exit 137 on docker stop
- Replace fixed sleep 3 with a polling loop (8 s ceiling) that exits as
soon as all processes have stopped
- Use pg_ctl stop -m immediate as the postgres force-stop fallback
instead of SIGKILL to avoid data corruption
- Add _cleanup_done guard to prevent double invocation of cleanup() when
the trap fires and the explicit call at script end both execute
- Register process names at startup in pid_names[] so crash diagnostics
show meaningful names after a process has exited
- Suppress the unexpected-exit diagnostic block on normal docker stop
- Guard all pgrep-based pids+=() against empty values (nginx, vite,
postgres) to prevent empty PID entries corrupting the pids[] array
fix: use psycopg2.sql for safe database drop and create commands
fix: Also check POSTGRES_SSL is true before skipping default POSTGRES_PASSWORD
fix: update usage comment to reflect correct script path
fix: improve cleanup logic to conditionally remove certificate directory
The auto-detect read PUID/PGID from /data/db ownership (UID 102 in pre-PUID images), causing all upgrading users to run as UID 102 instead of the expected UID 1000. This broke host-side access (SSH, WinSCP), made existing DATA_DIR files unwritable, and failed comskip on recordings created before the change.
DATA_DIRS chown failures (NFS, SMB/CIFS, FUSE) crashed the container under set -e. The old image never chowned these directories, so users with external mounts had a working setup that broke on upgrade with zero config changes.
- Collect mkdir and chown failures per-directory instead of crashing
- Emit a single consolidated warning listing all affected directories with current ownership and remediation steps
- Container continues to start; Django reports at runtime if it cannot write to a specific directory
- Local volumes are unaffected: chown still runs and succeeds silently
- replaced $_pg_tmp_port with $POSTRGES_PORT in migration logic. Works because "pg_ctl stop -w" is run before entrypoint.sh restarts postgres. Verified that this does not cause a race condition.
- Correcting unquoted environment variables to prevent inappropriate variables from causing execution inconsistencies (still unquoted in comments and prints)
PostgreSQL now runs as the PUID/PGID user ($POSTGRES_USER) instead of the internal postgres system user (UID 102). This fixes container startup failures when PUID/PGID is set, caused by chown permission errors on restricted filesystems (NFS root_squash, CIFS) and UID collisions with the postgres system user.
Changes:
- Run all PostgreSQL operations (initdb, pg_ctl, psql) as $POSTGRES_USER
- Auto-detect PUID/PGID from existing data owner when not explicitly set
- Validate PUID/PGID (reject zero, non-numeric values) before startup
- Migrate existing data ownership with sentinel-based skip optimization
- Use trust auth for local Unix sockets, md5 for network connections
- Add promote_app_role() and ensure_app_database() as idempotent startup guarantees that handle fresh installs, upgrades, and PUID changes
- Preserve postgres role as superuser for rollback compatibility
- Centralize /data/db ownership in 02-postgres.sh (sentinel-aware)
- Add integration test suite (20 scenarios) covering fresh installs, upgrades, restarts, PUID changes, UID collisions, bind mounts, modular mode, PG major upgrades, and end-to-end web UI verification
- Rewrite /etc/profile.d/dispatcharr.sh on every startup instead of only on first run, so container restarts with changed env vars pick up new values
- Quote exported values to prevent breakage from special characters in POSTGRES_PASSWORD or other vars
- Update /etc/environment entries instead of skipping if already present
- Move modular Redis wait from uWSGI exec-pre to entrypoint (exec-pre runs under 'su -' which strips Docker env vars, so DISPATCHARR_ENV and REDIS_HOST were never available)
- Selective flush in modular mode: clears stale app state (stream locks, proxy metadata) while preserving Celery broker/result keys
- AIO mode unchanged: full flushdb via uWSGI exec-pre
- Update unit tests for both flush paths
- Fix Postgres version check failing with restricted DB users (use $POSTGRES_DB instead of hardcoded 'postgres')
- Fix DVR recording broken in modular mode (respect DISPATCHARR_PORT instead of hardcoding 9191)
- Remove flushdb() from wait_for_redis.py to prevent Redis data loss on container restart
- Add DISPATCHARR_PORT to celery environment in docker-compose.yml
- Add depends_on health conditions for proper service startup ordering
- Add extra_hosts for host.docker.internal resolution on Linux
- Harden celery entrypoint with timeouts for JWT wait (120s) and migration wait (300s)
- Replace fragile showmigrations grep with migrate --check
- Add unit tests for DVR port resolution and flushdb removal regression
Replace raw Python AF_INET socket checks with pg_isready (PostgreSQL) and socket.create_connection (Redis) in modular deployment mode
The raw socket check may fail in some Docker environments depending on networking and DNS configurations, causing indefinite hangs. Replaced database check with native pg_isready
and memstore checck with AF_UNSPEC in the case IPv6 is enabled.
Fixes#952