- Added a new function `_is_uwsgi_worker` to accurately identify when the application is running within a uWSGI worker.
- Updated `get_process_role` to label processes as "uwsgi" based on the new function or command-line arguments, improving process role accuracy.
- Expanded unit tests to cover various scenarios for uWSGI role detection, ensuring robust validation of the new logic.
- 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