Fix modular mode deployment issues (#1045)

- 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
This commit is contained in:
None 2026-03-03 17:18:16 -06:00
parent 0db177b937
commit 6ff81e6287
8 changed files with 215 additions and 28 deletions

View file

@ -15,8 +15,12 @@ services:
volumes:
- ./data:/data
depends_on:
- db
- redis
db:
condition: service_healthy
redis:
condition: service_healthy
extra_hosts:
- "host.docker.internal:host-gateway"
# --- Environment Configuration ---
environment:
@ -83,9 +87,12 @@ services:
container_name: dispatcharr_celery
restart: unless-stopped
depends_on:
- db
- redis
- web
db:
condition: service_healthy
redis:
condition: service_healthy
web:
condition: service_started
volumes:
- ./data:/data
extra_hosts:
@ -97,6 +104,10 @@ services:
# Deployment Mode
- DISPATCHARR_ENV=modular
# Internal Service Communication
# Must match the web service port for DVR recording and internal API calls
- DISPATCHARR_PORT=9191
# PostgreSQL Connection
- POSTGRES_HOST=db
- POSTGRES_PORT=5432

View file

@ -9,9 +9,19 @@ echo_with_timestamp() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# Wait for Django secret key
# Wait for Django secret key (generated by the web container on startup)
JWT_TIMEOUT=120
JWT_WAITED=0
echo 'Waiting for Django secret key...'
while [ ! -f /data/jwt ]; do sleep 1; done
while [ ! -f /data/jwt ]; do
if [ $JWT_WAITED -ge $JWT_TIMEOUT ]; then
echo "❌ ERROR: Timed out waiting for /data/jwt after ${JWT_TIMEOUT}s."
echo " Is the web container running? Does it have the /data volume mounted?"
exit 1
fi
sleep 1
JWT_WAITED=$((JWT_WAITED + 1))
done
export DJANGO_SECRET_KEY="$(tr -d '\r\n' < /data/jwt)"
# --- NumPy version switching for legacy hardware ---
@ -26,11 +36,21 @@ if [ "$USE_LEGACY_NUMPY" = "true" ]; then
fi
fi
# Wait for migrations to complete (check that NO unapplied migrations remain)
# Wait for migrations to complete
# Uses 'migrate --check' which exits 0 only when all migrations are applied,
# and exits 1 on unapplied migrations OR connection errors (safe either way)
MIG_TIMEOUT=300
MIG_WAITED=0
echo 'Waiting for migrations to complete...'
until ! python manage.py showmigrations 2>&1 | grep -q '\[ \]'; do
until python manage.py migrate --check >/dev/null 2>&1; do
if [ $MIG_WAITED -ge $MIG_TIMEOUT ]; then
echo "❌ ERROR: Timed out waiting for migrations after ${MIG_TIMEOUT}s."
echo " Check web container logs for migration errors."
exit 1
fi
echo_with_timestamp 'Migrations not ready yet, waiting...'
sleep 2
MIG_WAITED=$((MIG_WAITED + 2))
done
# Start Celery

View file

@ -204,14 +204,19 @@ check_external_postgres_version() {
MIN_REQUIRED_VERSION=$PG_VERSION
# Query external PostgreSQL version
EXTERNAL_VERSION=$(PGPASSWORD="$POSTGRES_PASSWORD" psql -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "postgres" -tAc "SHOW server_version;" 2>/dev/null | grep -oE '^[0-9]+')
# Use $POSTGRES_DB — restricted users may not have access to the default 'postgres' database
PG_VERSION_ERR=$(mktemp)
EXTERNAL_VERSION=$(PGPASSWORD="$POSTGRES_PASSWORD" psql -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SHOW server_version;" 2>"$PG_VERSION_ERR" | grep -oE '^[0-9]+')
if [ -z "$EXTERNAL_VERSION" ]; then
echo "❌ ERROR: Unable to determine external PostgreSQL version"
echo " Could not connect to database at ${POSTGRES_HOST}:${POSTGRES_PORT}"
echo " Could not connect to database '$POSTGRES_DB' at ${POSTGRES_HOST}:${POSTGRES_PORT} as user '$POSTGRES_USER'"
echo " Error: $(cat "$PG_VERSION_ERR")"
echo " Please verify your database connection settings."
rm -f "$PG_VERSION_ERR"
return 1
fi
rm -f "$PG_VERSION_ERR"
# Compare versions
if [[ "$EXTERNAL_VERSION" -lt "$MIN_REQUIRED_VERSION" ]]; then