From 3706e63beddeeccc1b5809fdb4677f9f2ba49ca6 Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Wed, 21 Jan 2026 11:14:28 -0600 Subject: [PATCH 01/10] feat: Add DISPATCHARR_ENV=modular support for multi-container deployments - docker/entrypoint.sh: Conditional PostgreSQL init/startup for modular mode - docker/entrypoint.celery.sh: New dedicated entrypoint for celery container - prevents race condition in modular deployment - docker/uwsgi.modular.ini: New uWSGI config without Redis/Celery daemons - docker/Dockerfile: Add line ending fixes and chmod for entrypoints - adds cross-platform support for image builds - docker/docker-compose.yml: Configure modular mode with DISPATCHARR_ENV - uses new celery entrypoint and adds depends_on to prevent race condition --- docker/Dockerfile | 4 +++ docker/docker-compose.yml | 19 +++++++----- docker/entrypoint.celery.sh | 22 ++++++++++++++ docker/entrypoint.sh | 52 ++++++++++++++++++++++---------- docker/uwsgi.modular.ini | 59 +++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 23 deletions(-) create mode 100644 docker/entrypoint.celery.sh create mode 100644 docker/uwsgi.modular.ini diff --git a/docker/Dockerfile b/docker/Dockerfile index bfb35c11..409f1096 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -30,6 +30,10 @@ WORKDIR /app COPY . /app # Copy nginx configuration COPY ./docker/nginx.conf /etc/nginx/sites-enabled/default +# Verify entrypoint scripts exist, fix line endings, and make them executable +RUN ls -la /app/docker/entrypoint*.sh && \ + sed -i 's/\r$//' /app/docker/entrypoint.sh /app/docker/entrypoint.celery.sh /app/docker/entrypoint.aio.sh && \ + chmod +x /app/docker/entrypoint.sh /app/docker/entrypoint.celery.sh /app/docker/entrypoint.aio.sh # Clean out existing frontend folder RUN rm -rf /app/frontend # Copy built frontend assets diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e4093e4b..df295f90 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -10,6 +10,7 @@ services: - db - redis environment: + - DISPATCHARR_ENV=modular - POSTGRES_HOST=db - POSTGRES_DB=dispatcharr - POSTGRES_USER=dispatch @@ -25,7 +26,6 @@ services: # Lower values = higher priority. Range: -20 (highest) to 19 (lowest) # Negative values require cap_add: SYS_NICE (uncomment below) #- UWSGI_NICE_LEVEL=-5 # uWSGI/FFmpeg/Streaming (default: 0, recommended: -5 for high priority) - #- CELERY_NICE_LEVEL=5 # Celery/EPG/Background tasks (default: 5, low priority) # # Uncomment to enable high priority for streaming (required if UWSGI_NICE_LEVEL < 0) #cap_add: @@ -52,22 +52,27 @@ services: depends_on: - db - redis + - web volumes: - - ../:/app + - ./data:/data extra_hosts: - "host.docker.internal:host-gateway" environment: + - DISPATCHARR_ENV=modular - POSTGRES_HOST=db - POSTGRES_DB=dispatcharr - POSTGRES_USER=dispatch - POSTGRES_PASSWORD=secret - REDIS_HOST=redis - CELERY_BROKER_URL=redis://redis:6379/0 - command: > - bash -c " - cd /app && - nice -n 5 celery -A dispatcharr worker -l info - " + - DISPATCHARR_LOG_LEVEL=info + #- CELERY_NICE_LEVEL=5 #Celery/EPG/Background tasks (default:5, low priority; Range: -20 to 19) + - DJANGO_SETTINGS_MODULE=dispatcharr.settings + - PYTHONUNBUFFERED=1 + # Uncomment to enable high priority for Celery (required if CELERY_NICE_LEVEL < 0) + #cap_add: + # - SYS_NICE + entrypoint: ["/app/docker/entrypoint.celery.sh"] db: image: postgres:14 diff --git a/docker/entrypoint.celery.sh b/docker/entrypoint.celery.sh new file mode 100644 index 00000000..fafe2c3f --- /dev/null +++ b/docker/entrypoint.celery.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +cd /app +source /dispatcharrpy/bin/activate + +# Wait for Django secret key +echo 'Waiting for Django secret key...' +while [ ! -f /data/jwt ]; do sleep 1; done +export DJANGO_SECRET_KEY=$(cat /data/jwt) + +# Wait for migrations to complete +echo 'Waiting for migrations to complete...' +until python manage.py showmigrations 2>&1 | grep -q '\[X\]'; do + echo 'Migrations not ready yet, waiting...' + sleep 2 +done + +# Start Celery +echo 'Migrations complete, starting Celery...' +celery -A dispatcharr beat -l info & +nice -n ${CELERY_NICE_LEVEL:-5} celery -A dispatcharr worker -l info --autoscale=6,1 diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index a50f2f49..36948c1f 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -150,26 +150,43 @@ fi # Run init scripts echo "Starting user setup..." . /app/docker/init/01-user-setup.sh -echo "Setting up PostgreSQL..." -. /app/docker/init/02-postgres.sh + +# Initialize PostgreSQL if NOT in modular mode (using external database) +if [[ "$DISPATCHARR_ENV" != "modular" ]]; then + echo "Setting up PostgreSQL..." + . /app/docker/init/02-postgres.sh +fi + echo "Starting init process..." . /app/docker/init/03-init-dispatcharr.sh -# Start PostgreSQL -echo "Starting Postgres..." -su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} start -w -t 300 -o '-c port=${POSTGRES_PORT}'" -# Wait for PostgreSQL to be ready -until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do - echo_with_timestamp "Waiting for PostgreSQL to be ready..." - sleep 1 -done -postgres_pid=$(su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} status" | sed -n 's/.*PID: \([0-9]\+\).*/\1/p') -echo "✅ Postgres started with PID $postgres_pid" -pids+=("$postgres_pid") +# Start PostgreSQL if NOT in modular mode (using external database) +if [[ "$DISPATCHARR_ENV" != "modular" ]]; then + echo "Starting Postgres..." + su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} start -w -t 300 -o '-c port=${POSTGRES_PORT}'" + # Wait for PostgreSQL to be ready + until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do + echo_with_timestamp "Waiting for PostgreSQL to be ready..." + sleep 1 + done + postgres_pid=$(su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} status" | sed -n 's/.*PID: \([0-9]\+\).*/\1/p') + echo "✅ Postgres started with PID $postgres_pid" + pids+=("$postgres_pid") +else + echo "🔗 Modular mode: Using external PostgreSQL at ${POSTGRES_HOST}:${POSTGRES_PORT}" + # Wait for external PostgreSQL to be ready + echo_with_timestamp "Waiting for external PostgreSQL to be ready..." + until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do + echo_with_timestamp "Waiting for PostgreSQL at ${POSTGRES_HOST}:${POSTGRES_PORT}..." + sleep 1 + done + echo "✅ External PostgreSQL is ready" +fi -# Ensure database encoding is UTF8 -. /app/docker/init/02-postgres.sh -ensure_utf8_encoding +# Ensure database encoding is UTF8 (only for internal database) +if [[ "$DISPATCHARR_ENV" != "modular" ]]; then + ensure_utf8_encoding +fi if [[ "$DISPATCHARR_ENV" = "dev" ]]; then . /app/docker/init/99-init-dev.sh @@ -197,6 +214,9 @@ if [ "$DISPATCHARR_ENV" = "dev" ] && [ "$DISPATCHARR_DEBUG" != "true" ]; then elif [ "$DISPATCHARR_DEBUG" = "true" ]; then echo "🚀 Starting uwsgi in debug mode..." uwsgi_file="/app/docker/uwsgi.debug.ini" +elif [ "$DISPATCHARR_ENV" = "modular" ]; then + echo "🚀 Starting uwsgi in modular mode..." + uwsgi_file="/app/docker/uwsgi.modular.ini" else echo "🚀 Starting uwsgi in production mode..." uwsgi_file="/app/docker/uwsgi.ini" diff --git a/docker/uwsgi.modular.ini b/docker/uwsgi.modular.ini new file mode 100644 index 00000000..3220a8d8 --- /dev/null +++ b/docker/uwsgi.modular.ini @@ -0,0 +1,59 @@ +[uwsgi] +; Modular deployment mode - external PostgreSQL, Redis, and Celery +; Remove file creation commands since we're not logging to files anymore +; exec-pre = mkdir -p /data/logs +; exec-pre = touch /data/logs/uwsgi.log +; exec-pre = chmod 666 /data/logs/uwsgi.log + +; First run Redis availability check script once +exec-pre = python /app/scripts/wait_for_redis.py + +; Start Daphne for WebSocket support (required for real-time features) +; Redis and Celery run in separate containers in modular mode +attach-daemon = daphne -b 0.0.0.0 -p 8001 dispatcharr.asgi:application + +# Core settings +chdir = /app +module = dispatcharr.wsgi:application +virtualenv = /dispatcharrpy +master = true +env = DJANGO_SETTINGS_MODULE=dispatcharr.settings +env = USE_NGINX_ACCEL=true +socket = /app/uwsgi.sock +chmod-socket = 777 +vacuum = true +die-on-term = true +static-map = /static=/app/static + +# Worker management +workers = 4 + +# Optimize for streaming +http = 0.0.0.0:5656 +http-keepalive = 1 +buffer-size = 65536 # Increase buffer for large payloads +post-buffering = 4096 # Reduce buffering for real-time streaming +http-timeout = 600 # Prevent disconnects from long streams +socket-timeout = 600 # Prevent write timeouts when client buffers +lazy-apps = true # Improve memory efficiency + +# Async mode (use gevent for high concurrency) +gevent = 400 # Each unused greenlet costs ~2-4KB of memory +# Higher values have minimal performance impact when idle, but provide capacity for traffic spikes +# If memory usage becomes an issue, reduce this value + +# Performance tuning +thunder-lock = true +log-4xx = true +log-5xx = true +disable-logging = false + +# Logging configuration +# Enable console logging (stdout) +log-master = true +# Enable strftime formatting for timestamps +logformat-strftime = true +log-date = %%Y-%%m-%%d %%H:%%M:%%S,000 +# Use formatted time with environment variable for log level +log-format = %(ftime) $(DISPATCHARR_LOG_LEVEL) uwsgi.requests Worker ID: %(wid) %(method) %(status) %(uri) %(msecs)ms +log-buffering = 1024 # Add buffer size limit for logging From 236b2307e1e7878ddb2a2bb67ea4ede7312479cd Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Wed, 21 Jan 2026 17:40:36 -0600 Subject: [PATCH 02/10] Add health check and fix dangerous checks - docker-compose: added service health checks - dockerfile: added if logic for sed command so missing files do not cause build fail - entrypoint.celery: change migration detection to not continue until ALL migrations are applied - entrypoint: trim django key and change external postgres check to python in case postgres binaries are missing --- docker/Dockerfile | 10 ++++++---- docker/docker-compose.yml | 25 ++++++++++++++++++++----- docker/entrypoint.celery.sh | 6 +++--- docker/entrypoint.sh | 17 ++++++++++++++--- 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 409f1096..3e30a825 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -30,10 +30,12 @@ WORKDIR /app COPY . /app # Copy nginx configuration COPY ./docker/nginx.conf /etc/nginx/sites-enabled/default -# Verify entrypoint scripts exist, fix line endings, and make them executable -RUN ls -la /app/docker/entrypoint*.sh && \ - sed -i 's/\r$//' /app/docker/entrypoint.sh /app/docker/entrypoint.celery.sh /app/docker/entrypoint.aio.sh && \ - chmod +x /app/docker/entrypoint.sh /app/docker/entrypoint.celery.sh /app/docker/entrypoint.aio.sh +# Fix line endings and make entrypoint scripts executable +RUN for f in /app/docker/entrypoint*.sh; do \ + if [ -f "$f" ]; then \ + sed -i 's/\r$//' "$f" && chmod +x "$f"; \ + fi; \ + done # Clean out existing frontend folder RUN rm -rf /app/frontend # Copy built frontend assets diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index df295f90..e9254d30 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -7,8 +7,10 @@ services: volumes: - ./data:/data depends_on: - - db - - redis + db: + condition: service_healthy + redis: + condition: service_healthy environment: - DISPATCHARR_ENV=modular - POSTGRES_HOST=db @@ -50,9 +52,12 @@ services: image: ghcr.io/dispatcharr/dispatcharr:latest container_name: dispatcharr_celery depends_on: - - db - - redis - - web + db: + condition: service_healthy + redis: + condition: service_healthy + web: + condition: service_started volumes: - ./data:/data extra_hosts: @@ -85,10 +90,20 @@ services: - POSTGRES_PASSWORD=secret volumes: - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U dispatch -d dispatcharr"] + interval: 5s + timeout: 5s + retries: 5 redis: image: redis:latest container_name: dispatcharr_redis + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 5 volumes: postgres_data: diff --git a/docker/entrypoint.celery.sh b/docker/entrypoint.celery.sh index fafe2c3f..0516cc54 100644 --- a/docker/entrypoint.celery.sh +++ b/docker/entrypoint.celery.sh @@ -7,11 +7,11 @@ source /dispatcharrpy/bin/activate # Wait for Django secret key echo 'Waiting for Django secret key...' while [ ! -f /data/jwt ]; do sleep 1; done -export DJANGO_SECRET_KEY=$(cat /data/jwt) +export DJANGO_SECRET_KEY="$(tr -d '\r\n' < /data/jwt)" -# Wait for migrations to complete +# Wait for migrations to complete (check that NO unapplied migrations remain) echo 'Waiting for migrations to complete...' -until python manage.py showmigrations 2>&1 | grep -q '\[X\]'; do +until ! python manage.py showmigrations 2>&1 | grep -q '\[ \]'; do echo 'Migrations not ready yet, waiting...' sleep 2 done diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 36948c1f..0c17b9d0 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -66,7 +66,7 @@ PY mv -f "$tmpfile" "$SECRET_FILE" || { echo "move failed"; rm -f "$tmpfile"; exit 1; } umask $old_umask fi -export DJANGO_SECRET_KEY="$(cat "$SECRET_FILE")" +export DJANGO_SECRET_KEY="$(tr -d '\r\n' < "$SECRET_FILE")" # Process priority configuration # UWSGI_NICE_LEVEL: Absolute nice value for uWSGI/streaming (default: 0 = normal priority) @@ -174,9 +174,20 @@ if [[ "$DISPATCHARR_ENV" != "modular" ]]; then pids+=("$postgres_pid") else echo "🔗 Modular mode: Using external PostgreSQL at ${POSTGRES_HOST}:${POSTGRES_PORT}" - # Wait for external PostgreSQL to be ready + # Wait for external PostgreSQL to be ready using Python (no pg_isready needed) echo_with_timestamp "Waiting for external PostgreSQL to be ready..." - until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do + until python3 -c " +import socket +import sys +try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(2) + s.connect(('${POSTGRES_HOST}', ${POSTGRES_PORT})) + s.close() + sys.exit(0) +except Exception: + sys.exit(1) +" 2>/dev/null; do echo_with_timestamp "Waiting for PostgreSQL at ${POSTGRES_HOST}:${POSTGRES_PORT}..." sleep 1 done From 7a46577d2ec89ac65f20ae7249cc4194659fde7e Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Wed, 21 Jan 2026 17:46:07 -0600 Subject: [PATCH 03/10] Remove health check conditions Not supported on compose v3+ --- docker/docker-compose.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e9254d30..6673f896 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -7,10 +7,8 @@ services: volumes: - ./data:/data depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy + - db + - redis environment: - DISPATCHARR_ENV=modular - POSTGRES_HOST=db @@ -52,12 +50,9 @@ services: image: ghcr.io/dispatcharr/dispatcharr:latest container_name: dispatcharr_celery depends_on: - db: - condition: service_healthy - redis: - condition: service_healthy - web: - condition: service_started + - db + - redis + - web volumes: - ./data:/data extra_hosts: From 8c2ffbe76a82972de35493826b3d29591e2240cf Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Wed, 21 Jan 2026 17:59:23 -0600 Subject: [PATCH 04/10] CELERY_NICE_LEVEL warning Changed the celery entrypoint to include a warning if CELERY_NICE_LEVEL is negative AND SYS_NICE is not configured (SYS_NICE is required for negative levels) --- docker/entrypoint.celery.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docker/entrypoint.celery.sh b/docker/entrypoint.celery.sh index 0516cc54..81cece86 100644 --- a/docker/entrypoint.celery.sh +++ b/docker/entrypoint.celery.sh @@ -19,4 +19,11 @@ done # Start Celery echo 'Migrations complete, starting Celery...' celery -A dispatcharr beat -l info & -nice -n ${CELERY_NICE_LEVEL:-5} celery -A dispatcharr worker -l info --autoscale=6,1 + +# Default to nice level 5 (lower priority) - safe for unprivileged containers +# Negative values require SYS_NICE capability +NICE_LEVEL="${CELERY_NICE_LEVEL:-5}" +if [ "$NICE_LEVEL" -lt 0 ] 2>/dev/null; then + echo "Warning: CELERY_NICE_LEVEL=$NICE_LEVEL is negative, requires SYS_NICE capability" +fi +nice -n "$NICE_LEVEL" celery -A dispatcharr worker -l info --autoscale=6,1 From 557e192d4c2df053fee966be0b8f70efe951c432 Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Fri, 23 Jan 2026 19:15:27 -0600 Subject: [PATCH 05/10] Add UTF8 encoding check for external databases Extend ensure_utf8_encoding() to support both internal and external PostgreSQL. - Modular mode: Uses TCP connection with PGPASSWORD authentication - AIO mode: Uses Unix socket as postgres user - Explicitly set database owner during recreation (fixes missing --owner flag) - Conversion logic (dump/drop/recreate/restore) works for both AIO and modular modes - Skip internal PostgreSQL setup entirely when DISPATCHARR_ENV=modular --- docker/entrypoint.sh | 14 ++++------ docker/init/02-postgres.sh | 54 +++++++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 0c17b9d0..f1515ee0 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -151,11 +151,9 @@ fi echo "Starting user setup..." . /app/docker/init/01-user-setup.sh -# Initialize PostgreSQL if NOT in modular mode (using external database) -if [[ "$DISPATCHARR_ENV" != "modular" ]]; then - echo "Setting up PostgreSQL..." - . /app/docker/init/02-postgres.sh -fi +# Initialize PostgreSQL (script handles modular vs internal mode internally) +echo "Setting up PostgreSQL..." +. /app/docker/init/02-postgres.sh echo "Starting init process..." . /app/docker/init/03-init-dispatcharr.sh @@ -194,10 +192,8 @@ except Exception: echo "✅ External PostgreSQL is ready" fi -# Ensure database encoding is UTF8 (only for internal database) -if [[ "$DISPATCHARR_ENV" != "modular" ]]; then - ensure_utf8_encoding -fi +# Ensure database encoding is UTF8 (handles both internal and external databases) +ensure_utf8_encoding if [[ "$DISPATCHARR_ENV" = "dev" ]]; then . /app/docker/init/99-init-dev.sh diff --git a/docker/init/02-postgres.sh b/docker/init/02-postgres.sh index e36dd744..a9237df0 100644 --- a/docker/init/02-postgres.sh +++ b/docker/init/02-postgres.sh @@ -1,4 +1,8 @@ #!/bin/bash + +# Skip internal PostgreSQL setup in modular mode (using external database) +if [[ "$DISPATCHARR_ENV" != "modular" ]]; then + # Temporary migration from postgres in /data to $POSTGRES_DIR. Can likely remove # some time in the future. if [ -e "/data/postgresql.conf" ]; then @@ -139,27 +143,51 @@ EOF done fi +fi # End of DISPATCHARR_ENV != modular check + ensure_utf8_encoding() { # Check encoding of existing database - CURRENT_ENCODING=$(su - postgres -c "psql -p ${POSTGRES_PORT} -tAc \"SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = '$POSTGRES_DB';\"" | tr -d ' ') + # Supports both internal (Unix socket) and external (TCP) PostgreSQL + echo "Checking database encoding..." + + if [[ "$DISPATCHARR_ENV" == "modular" ]]; then + # External database: use TCP connection with password + CURRENT_ENCODING=$(PGPASSWORD="$POSTGRES_PASSWORD" psql -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -tAc "SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database();" 2>/dev/null | tr -d ' ') + else + # Internal database: use Unix socket as postgres user + CURRENT_ENCODING=$(su - postgres -c "psql -p ${POSTGRES_PORT} -d ${POSTGRES_DB} -tAc \"SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database();\"" | tr -d ' ') + fi + if [ "$CURRENT_ENCODING" != "UTF8" ]; then echo "Database $POSTGRES_DB encoding is $CURRENT_ENCODING, converting to UTF8..." DUMP_FILE="/tmp/${POSTGRES_DB}_utf8_dump_$(date +%s).sql" - # Dump database (include permissions and ownership) - su - postgres -c "pg_dump -p ${POSTGRES_PORT} $POSTGRES_DB > $DUMP_FILE" - # Drop and recreate database with UTF8 encoding using template0 - su - postgres -c "dropdb -p ${POSTGRES_PORT} $POSTGRES_DB" - # Recreate database with UTF8 encoding - su - postgres -c "createdb -p ${POSTGRES_PORT} --encoding=UTF8 --template=template0 ${POSTGRES_DB}" - - - # Restore data - su - postgres -c "psql -p ${POSTGRES_PORT} -d $POSTGRES_DB < $DUMP_FILE" - #configure_db + if [[ "$DISPATCHARR_ENV" == "modular" ]]; then + # External database: use TCP connection with password + # Dump database (include permissions and ownership) + PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" "$POSTGRES_DB" > "$DUMP_FILE" || { echo "Dump failed"; return 1; } + # Drop and recreate database with UTF8 encoding using template0 + PGPASSWORD="$POSTGRES_PASSWORD" dropdb -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" "$POSTGRES_DB" || { echo "Drop failed"; return 1; } + # Recreate database with UTF8 encoding + PGPASSWORD="$POSTGRES_PASSWORD" createdb -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" --encoding=UTF8 --template=template0 "$POSTGRES_DB" || { echo "Create failed"; return 1; } + # Restore data + PGPASSWORD="$POSTGRES_PASSWORD" psql -w -h "$POSTGRES_HOST" -p "$POSTGRES_PORT" -U "$POSTGRES_USER" -d "$POSTGRES_DB" < "$DUMP_FILE" || { echo "Restore failed"; return 1; } + else + # Internal database: use Unix socket as postgres user + # Dump database (include permissions and ownership) + su - postgres -c "pg_dump -p ${POSTGRES_PORT} ${POSTGRES_DB}" > "$DUMP_FILE" || { echo "Dump failed"; return 1; } + # Drop and recreate database with UTF8 encoding using template0 + su - postgres -c "dropdb -p ${POSTGRES_PORT} ${POSTGRES_DB}" || { echo "Drop failed"; return 1; } + # Recreate database with UTF8 encoding and correct owner + su - postgres -c "createdb -p ${POSTGRES_PORT} --encoding=UTF8 --template=template0 --owner=${POSTGRES_USER} ${POSTGRES_DB}" || { echo "Create failed"; return 1; } + # Restore data + cat "$DUMP_FILE" | su - postgres -c "psql -p ${POSTGRES_PORT} -d ${POSTGRES_DB}" || { echo "Restore failed"; return 1; } + fi rm -f "$DUMP_FILE" - echo "Database $POSTGRES_DB converted to UTF8 and permissions set." + echo "✅ Database $POSTGRES_DB converted to UTF8." + else + echo "✅ Database encoding is UTF8" fi } From 47b591bacb7e38d3d617ca1ecbc8c08b5050672a Mon Sep 17 00:00:00 2001 From: Matt Grutza Date: Fri, 23 Jan 2026 21:28:53 -0600 Subject: [PATCH 06/10] Add configurable POSTGRES_PORT and REDIS_PORT for external databases Make database ports configurable for users with external PostgreSQL/Redis. - Add POSTGRES_PORT and REDIS_PORT to docker-compose.yml (web and celery) - Remove hardcoded CELERY_BROKER_URL (Django builds it from components) - Add REDIS_PORT export to entrypoint.sh and profile variables - Add Redis connection check for modular mode (matches PostgreSQL pattern) Users can now specify custom ports for external databases: [defaults] POSTGRES_PORT=5432 REDIS_PORT=6379 --- docker/docker-compose.yml | 6 ++++-- docker/entrypoint.sh | 25 ++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 6673f896..9d921c2d 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -12,11 +12,12 @@ services: environment: - DISPATCHARR_ENV=modular - POSTGRES_HOST=db + - POSTGRES_PORT=5432 - POSTGRES_DB=dispatcharr - POSTGRES_USER=dispatch - POSTGRES_PASSWORD=secret - REDIS_HOST=redis - - CELERY_BROKER_URL=redis://redis:6379/0 + - REDIS_PORT=6379 - DISPATCHARR_LOG_LEVEL=info # Legacy CPU Support (Optional) # Uncomment to enable legacy NumPy build for older CPUs (circa 2009) @@ -60,11 +61,12 @@ services: environment: - DISPATCHARR_ENV=modular - POSTGRES_HOST=db + - POSTGRES_PORT=5432 - POSTGRES_DB=dispatcharr - POSTGRES_USER=dispatch - POSTGRES_PASSWORD=secret - REDIS_HOST=redis - - CELERY_BROKER_URL=redis://redis:6379/0 + - REDIS_PORT=6379 - DISPATCHARR_LOG_LEVEL=info #- CELERY_NICE_LEVEL=5 #Celery/EPG/Background tasks (default:5, low priority; Range: -20 to 19) - DJANGO_SETTINGS_MODULE=dispatcharr.settings diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index f1515ee0..e6fa8ef0 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -48,6 +48,7 @@ export POSTGRES_PORT=${POSTGRES_PORT:-5432} export PG_VERSION=$(ls /usr/lib/postgresql/ | sort -V | tail -n 1) export PG_BINDIR="/usr/lib/postgresql/${PG_VERSION}/bin" export REDIS_HOST=${REDIS_HOST:-localhost} +export REDIS_PORT=${REDIS_PORT:-6379} export REDIS_DB=${REDIS_DB:-0} export DISPATCHARR_PORT=${DISPATCHARR_PORT:-9191} export LIBVA_DRIVERS_PATH='/usr/local/lib/x86_64-linux-gnu/dri' @@ -115,7 +116,7 @@ if [[ ! -f /etc/profile.d/dispatcharr.sh ]]; then PATH VIRTUAL_ENV DJANGO_SETTINGS_MODULE PYTHONUNBUFFERED PYTHONDONTWRITEBYTECODE POSTGRES_DB POSTGRES_USER POSTGRES_PASSWORD POSTGRES_HOST POSTGRES_PORT DISPATCHARR_ENV DISPATCHARR_DEBUG DISPATCHARR_LOG_LEVEL - REDIS_HOST REDIS_DB POSTGRES_DIR DISPATCHARR_PORT + REDIS_HOST REDIS_PORT REDIS_DB POSTGRES_DIR DISPATCHARR_PORT DISPATCHARR_VERSION DISPATCHARR_TIMESTAMP LIBVA_DRIVERS_PATH LIBVA_DRIVER_NAME LD_LIBRARY_PATH CELERY_NICE_LEVEL UWSGI_NICE_LEVEL DJANGO_SECRET_KEY ) @@ -192,6 +193,28 @@ except Exception: echo "✅ External PostgreSQL is ready" fi +# Wait for Redis to be ready (modular mode uses external Redis) +if [[ "$DISPATCHARR_ENV" == "modular" ]]; then + echo "🔗 Modular mode: Using external Redis at ${REDIS_HOST}:${REDIS_PORT}" + echo_with_timestamp "Waiting for external Redis to be ready..." + until python3 -c " +import socket +import sys +try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(2) + s.connect(('${REDIS_HOST}', ${REDIS_PORT})) + s.close() + sys.exit(0) +except Exception: + sys.exit(1) +" 2>/dev/null; do + echo_with_timestamp "Waiting for Redis at ${REDIS_HOST}:${REDIS_PORT}..." + sleep 1 + done + echo "✅ External Redis is ready" +fi + # Ensure database encoding is UTF8 (handles both internal and external databases) ensure_utf8_encoding From 8de22fc44dc64b2558f77f3402db20a6e05111ff Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Thu, 29 Jan 2026 10:22:07 -0600 Subject: [PATCH 07/10] Indent modular if statement for readability. --- docker/init/02-postgres.sh | 226 ++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/docker/init/02-postgres.sh b/docker/init/02-postgres.sh index a9237df0..972dea06 100644 --- a/docker/init/02-postgres.sh +++ b/docker/init/02-postgres.sh @@ -3,125 +3,125 @@ # Skip internal PostgreSQL setup in modular mode (using external database) if [[ "$DISPATCHARR_ENV" != "modular" ]]; then -# Temporary migration from postgres in /data to $POSTGRES_DIR. Can likely remove -# some time in the future. -if [ -e "/data/postgresql.conf" ]; then - echo "Migrating PostgreSQL data from /data to $POSTGRES_DIR..." + # Temporary migration from postgres in /data to $POSTGRES_DIR. Can likely remove + # some time in the future. + if [ -e "/data/postgresql.conf" ]; then + echo "Migrating PostgreSQL data from /data to $POSTGRES_DIR..." - # Create a temporary directory outside of /data - mkdir -p /tmp/postgres_migration + # Create a temporary directory outside of /data + mkdir -p /tmp/postgres_migration - # Move the PostgreSQL files to the temporary directory - mv /data/* /tmp/postgres_migration/ + # Move the PostgreSQL files to the temporary directory + mv /data/* /tmp/postgres_migration/ - # Create the target directory - mkdir -p $POSTGRES_DIR + # Create the target directory + mkdir -p $POSTGRES_DIR - # Move the files from temporary directory to the final location - mv /tmp/postgres_migration/* $POSTGRES_DIR/ + # Move the files from temporary directory to the final location + mv /tmp/postgres_migration/* $POSTGRES_DIR/ - # Clean up the temporary directory - rmdir /tmp/postgres_migration + # Clean up the temporary directory + rmdir /tmp/postgres_migration - # Set proper ownership and permissions for PostgreSQL data directory - chown -R postgres:postgres $POSTGRES_DIR - chmod 700 $POSTGRES_DIR + # Set proper ownership and permissions for PostgreSQL data directory + chown -R postgres:postgres $POSTGRES_DIR + chmod 700 $POSTGRES_DIR - echo "Migration completed successfully." -fi + echo "Migration completed successfully." + fi -PG_VERSION_FILE="${POSTGRES_DIR}/PG_VERSION" + PG_VERSION_FILE="${POSTGRES_DIR}/PG_VERSION" -# Detect current version from data directory, if present -if [ -f "$PG_VERSION_FILE" ]; then - CURRENT_VERSION=$(cat "$PG_VERSION_FILE") -else - CURRENT_VERSION="" -fi + # Detect current version from data directory, if present + if [ -f "$PG_VERSION_FILE" ]; then + CURRENT_VERSION=$(cat "$PG_VERSION_FILE") + else + CURRENT_VERSION="" + fi -# Only run upgrade if current version is set and not the target -if [ -n "$CURRENT_VERSION" ] && [ "$CURRENT_VERSION" != "$PG_VERSION" ]; then - echo "Detected PostgreSQL data directory version $CURRENT_VERSION, upgrading to $PG_VERSION..." - # Set binary paths for upgrade if needed - OLD_BINDIR="/usr/lib/postgresql/${CURRENT_VERSION}/bin" - NEW_BINDIR="/usr/lib/postgresql/${PG_VERSION}/bin" - PG_INSTALLED_BY_SCRIPT=0 - if [ ! -d "$OLD_BINDIR" ]; then - echo "PostgreSQL binaries for version $CURRENT_VERSION not found. Installing..." - apt update && apt install -y postgresql-$CURRENT_VERSION postgresql-contrib-$CURRENT_VERSION - if [ $? -ne 0 ]; then - echo "Failed to install PostgreSQL version $CURRENT_VERSION. Exiting." - exit 1 + # Only run upgrade if current version is set and not the target + if [ -n "$CURRENT_VERSION" ] && [ "$CURRENT_VERSION" != "$PG_VERSION" ]; then + echo "Detected PostgreSQL data directory version $CURRENT_VERSION, upgrading to $PG_VERSION..." + # Set binary paths for upgrade if needed + OLD_BINDIR="/usr/lib/postgresql/${CURRENT_VERSION}/bin" + NEW_BINDIR="/usr/lib/postgresql/${PG_VERSION}/bin" + PG_INSTALLED_BY_SCRIPT=0 + if [ ! -d "$OLD_BINDIR" ]; then + echo "PostgreSQL binaries for version $CURRENT_VERSION not found. Installing..." + apt update && apt install -y postgresql-$CURRENT_VERSION postgresql-contrib-$CURRENT_VERSION + if [ $? -ne 0 ]; then + echo "Failed to install PostgreSQL version $CURRENT_VERSION. Exiting." + exit 1 + fi + PG_INSTALLED_BY_SCRIPT=1 + fi + + # Prepare new data directory + NEW_POSTGRES_DIR="${POSTGRES_DIR}_$PG_VERSION" + + # Remove new data directory if it already exists (from a failed/partial upgrade) + if [ -d "$NEW_POSTGRES_DIR" ]; then + echo "Warning: $NEW_POSTGRES_DIR already exists. Removing it to avoid upgrade issues." + rm -rf "$NEW_POSTGRES_DIR" + fi + + mkdir -p "$NEW_POSTGRES_DIR" + chown -R postgres:postgres "$NEW_POSTGRES_DIR" + chmod 700 "$NEW_POSTGRES_DIR" + + # Initialize new data directory + echo "Initializing new PostgreSQL data directory at $NEW_POSTGRES_DIR..." + su - postgres -c "$NEW_BINDIR/initdb -D $NEW_POSTGRES_DIR" + echo "Running pg_upgrade from $OLD_BINDIR to $NEW_BINDIR..." + # Run pg_upgrade + su - postgres -c "$NEW_BINDIR/pg_upgrade -b $OLD_BINDIR -B $NEW_BINDIR -d $POSTGRES_DIR -D $NEW_POSTGRES_DIR" + + # Move old data directory for backup, move new into place + mv "$POSTGRES_DIR" "${POSTGRES_DIR}_backup_${CURRENT_VERSION}_$(date +%s)" + mv "$NEW_POSTGRES_DIR" "$POSTGRES_DIR" + + echo "Upgrade complete. Old data directory backed up." + + # Uninstall PostgreSQL if we installed it just for upgrade + if [ "$PG_INSTALLED_BY_SCRIPT" -eq 1 ]; then + echo "Uninstalling temporary PostgreSQL $CURRENT_VERSION packages..." + apt remove -y postgresql-$CURRENT_VERSION postgresql-contrib-$CURRENT_VERSION + apt autoremove -y fi - PG_INSTALLED_BY_SCRIPT=1 fi - # Prepare new data directory - NEW_POSTGRES_DIR="${POSTGRES_DIR}_$PG_VERSION" + # Initialize PostgreSQL database + if [ -z "$(ls -A $POSTGRES_DIR)" ]; then + echo "Initializing PostgreSQL database..." + mkdir -p $POSTGRES_DIR + chown -R postgres:postgres $POSTGRES_DIR + chmod 700 $POSTGRES_DIR - # Remove new data directory if it already exists (from a failed/partial upgrade) - if [ -d "$NEW_POSTGRES_DIR" ]; then - echo "Warning: $NEW_POSTGRES_DIR already exists. Removing it to avoid upgrade issues." - rm -rf "$NEW_POSTGRES_DIR" - fi + # Initialize PostgreSQL + su - postgres -c "$PG_BINDIR/initdb -D ${POSTGRES_DIR}" + # Configure PostgreSQL + echo "host all all 0.0.0.0/0 md5" >> "${POSTGRES_DIR}/pg_hba.conf" + echo "listen_addresses='*'" >> "${POSTGRES_DIR}/postgresql.conf" - mkdir -p "$NEW_POSTGRES_DIR" - chown -R postgres:postgres "$NEW_POSTGRES_DIR" - chmod 700 "$NEW_POSTGRES_DIR" + # Start PostgreSQL + echo "Starting Postgres..." + su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} start -w -t 300 -o '-c port=${POSTGRES_PORT}'" + # Wait for PostgreSQL to be ready + until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do + echo "Waiting for PostgreSQL to be ready..." + sleep 1 + done - # Initialize new data directory - echo "Initializing new PostgreSQL data directory at $NEW_POSTGRES_DIR..." - su - postgres -c "$NEW_BINDIR/initdb -D $NEW_POSTGRES_DIR" - echo "Running pg_upgrade from $OLD_BINDIR to $NEW_BINDIR..." - # Run pg_upgrade - su - postgres -c "$NEW_BINDIR/pg_upgrade -b $OLD_BINDIR -B $NEW_BINDIR -d $POSTGRES_DIR -D $NEW_POSTGRES_DIR" + postgres_pid=$(su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} status" | sed -n 's/.*PID: \([0-9]\+\).*/\1/p') - # Move old data directory for backup, move new into place - mv "$POSTGRES_DIR" "${POSTGRES_DIR}_backup_${CURRENT_VERSION}_$(date +%s)" - mv "$NEW_POSTGRES_DIR" "$POSTGRES_DIR" - - echo "Upgrade complete. Old data directory backed up." - - # Uninstall PostgreSQL if we installed it just for upgrade - if [ "$PG_INSTALLED_BY_SCRIPT" -eq 1 ]; then - echo "Uninstalling temporary PostgreSQL $CURRENT_VERSION packages..." - apt remove -y postgresql-$CURRENT_VERSION postgresql-contrib-$CURRENT_VERSION - apt autoremove -y - fi -fi - -# Initialize PostgreSQL database -if [ -z "$(ls -A $POSTGRES_DIR)" ]; then - echo "Initializing PostgreSQL database..." - mkdir -p $POSTGRES_DIR - chown -R postgres:postgres $POSTGRES_DIR - chmod 700 $POSTGRES_DIR - - # Initialize PostgreSQL - su - postgres -c "$PG_BINDIR/initdb -D ${POSTGRES_DIR}" - # Configure PostgreSQL - echo "host all all 0.0.0.0/0 md5" >> "${POSTGRES_DIR}/pg_hba.conf" - echo "listen_addresses='*'" >> "${POSTGRES_DIR}/postgresql.conf" - - # Start PostgreSQL - echo "Starting Postgres..." - su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} start -w -t 300 -o '-c port=${POSTGRES_PORT}'" - # Wait for PostgreSQL to be ready - until su - postgres -c "$PG_BINDIR/pg_isready -h ${POSTGRES_HOST} -p ${POSTGRES_PORT}" >/dev/null 2>&1; do - echo "Waiting for PostgreSQL to be ready..." - sleep 1 - done - - postgres_pid=$(su - postgres -c "$PG_BINDIR/pg_ctl -D ${POSTGRES_DIR} status" | sed -n 's/.*PID: \([0-9]\+\).*/\1/p') - - # Setup database if needed - if ! su - postgres -c "psql -p ${POSTGRES_PORT} -tAc \"SELECT 1 FROM pg_database WHERE datname = '$POSTGRES_DB';\"" | grep -q 1; then - # Create PostgreSQL database - echo "Creating PostgreSQL database..." - su - postgres -c "createdb -p ${POSTGRES_PORT} --encoding=UTF8 ${POSTGRES_DB}" - # Create user, set ownership, and grant privileges - echo "Creating PostgreSQL user..." - su - postgres -c "psql -p ${POSTGRES_PORT} -d ${POSTGRES_DB}" < Date: Thu, 29 Jan 2026 10:42:34 -0600 Subject: [PATCH 08/10] Bump modular postgres to 17 from 14 to match AIO. --- docker/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 9d921c2d..c8e2d53e 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -77,7 +77,7 @@ services: entrypoint: ["/app/docker/entrypoint.celery.sh"] db: - image: postgres:14 + image: postgres:17 container_name: dispatcharr_db ports: - "5436:5432" From 8eef0889504018a17f36f96f0444519d7f79eff4 Mon Sep 17 00:00:00 2001 From: None Date: Sat, 31 Jan 2026 20:45:39 -0600 Subject: [PATCH 09/10] Add PostgreSQL version check for modular deployments Implements automatic version validation for external databases in modular mode to ensure compatibility. Changes: - Added check_external_postgres_version() in 02-postgres.sh - Integrated version check in entrypoint.sh after database connection - Enforces minimum PostgreSQL version matching DispatcharrBase - Allows newer versions with forward compatibility notice - Rejects older versions with clear upgrade instructions The version requirement automatically scales when DispatcharrBase is updated, requiring no manual maintenance. Only applies to modular deployments using external databases; AIO deployments are unaffected. Tested and verified correct behavior with PostgreSQL v17, v18, and v16 --- docker/entrypoint.sh | 3 +++ docker/init/02-postgres.sh | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index e6fa8ef0..f53fadf8 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -191,6 +191,9 @@ except Exception: sleep 1 done echo "✅ External PostgreSQL is ready" + + # Check PostgreSQL version compatibility + check_external_postgres_version || exit 1 fi # Wait for Redis to be ready (modular mode uses external Redis) diff --git a/docker/init/02-postgres.sh b/docker/init/02-postgres.sh index 972dea06..012b5c09 100644 --- a/docker/init/02-postgres.sh +++ b/docker/init/02-postgres.sh @@ -191,4 +191,58 @@ ensure_utf8_encoding() { fi } +check_external_postgres_version() { + # Only check for modular deployments using external databases + if [[ "$DISPATCHARR_ENV" != "modular" ]]; then + return 0 + fi + + echo "🔍 Checking external PostgreSQL version compatibility..." + + # Get minimum required version from base image (set in entrypoint.sh) + # PG_VERSION is the version installed in DispatcharrBase + 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]+') + + 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 " Please verify your database connection settings." + return 1 + fi + + # Compare versions + if [[ "$EXTERNAL_VERSION" -lt "$MIN_REQUIRED_VERSION" ]]; then + # FAIL: Version too old + echo "" + echo "❌ ERROR: PostgreSQL version mismatch" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo " External Database: PostgreSQL $EXTERNAL_VERSION" + echo " Required Version: PostgreSQL $MIN_REQUIRED_VERSION or higher" + echo "" + echo " Your external PostgreSQL database is too old for Dispatcharr." + echo " Please upgrade to PostgreSQL $MIN_REQUIRED_VERSION or later." + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "" + return 1 + + elif [[ "$EXTERNAL_VERSION" -eq "$MIN_REQUIRED_VERSION" ]]; then + # MATCH: Exact version match + echo "✅ PostgreSQL version check passed" + echo " External Database: PostgreSQL $EXTERNAL_VERSION (matches target version)" + + else + # HIGHER: Newer version + echo "✅ PostgreSQL version check passed" + echo " External Database: PostgreSQL $EXTERNAL_VERSION" + echo " Target Version: PostgreSQL $MIN_REQUIRED_VERSION" + echo " â„šī¸ Your database is newer than the target version." + echo " PostgreSQL version should be compatible with Dispatcharr." + fi + + return 0 +} + From 762949e983a18b7dd6bd0344314bf72247ce09c2 Mon Sep 17 00:00:00 2001 From: None Date: Sat, 31 Jan 2026 20:48:54 -0600 Subject: [PATCH 10/10] Update verbiage for consistency --- docker/init/02-postgres.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/init/02-postgres.sh b/docker/init/02-postgres.sh index 012b5c09..87aa94ef 100644 --- a/docker/init/02-postgres.sh +++ b/docker/init/02-postgres.sh @@ -192,7 +192,7 @@ ensure_utf8_encoding() { } check_external_postgres_version() { - # Only check for modular deployments using external databases + # Only check for modular deployments if [[ "$DISPATCHARR_ENV" != "modular" ]]; then return 0 fi @@ -200,7 +200,7 @@ check_external_postgres_version() { echo "🔍 Checking external PostgreSQL version compatibility..." # Get minimum required version from base image (set in entrypoint.sh) - # PG_VERSION is the version installed in DispatcharrBase + # PG_VERSION is from DispatcharrBase MIN_REQUIRED_VERSION=$PG_VERSION # Query external PostgreSQL version @@ -223,7 +223,7 @@ check_external_postgres_version() { echo " Required Version: PostgreSQL $MIN_REQUIRED_VERSION or higher" echo "" echo " Your external PostgreSQL database is too old for Dispatcharr." - echo " Please upgrade to PostgreSQL $MIN_REQUIRED_VERSION or later." + echo " Please upgrade to PostgreSQL $MIN_REQUIRED_VERSION or higher." echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "" return 1