mirror of
https://github.com/Dispatcharr/Dispatcharr.git
synced 2026-07-18 00:55:50 +00:00
feat: add TLS connection support for Redis and PostgreSQL (#950)
- Add 10 env vars for Redis/PostgreSQL TLS (REDIS_SSL, REDIS_SSL_VERIFY, REDIS_SSL_CA_CERT, REDIS_SSL_CERT, REDIS_SSL_KEY, POSTGRES_SSL, POSTGRES_SSL_MODE, POSTGRES_SSL_CA_CERT, POSTGRES_SSL_CERT, POSTGRES_SSL_KEY) - Propagate SSL params to all Redis connection points: RedisClient, stream view, PubSub, client manager, Celery broker/result backend, Django Channels, and pre-Django startup scripts - Add Celery SSL config via URL query string params (required by Kombu's internal URL parsing) - Add PostgreSQL sslmode and certificate options to DATABASES config - Add startup validation: cert file existence, URL scheme conflict detection, TLS status logging - Add TLS error hints to Redis connection failure messages - Add Connection Security panel in System Settings (modular mode only) showing encryption, verification, and mTLS status - Add PG client key permission fix in web and celery entrypoints for Docker Desktop compatibility (0777 to 0600) - Add TLS env var passthrough in entrypoint for su - login shells - Document TLS env vars in modular docker-compose.yml - Change env_mode from dev/prod to actual DISPATCHARR_ENV value for modular mode detection
This commit is contained in:
parent
874f5fce6a
commit
b30a24e2fb
16 changed files with 540 additions and 48 deletions
|
|
@ -14,6 +14,7 @@ services:
|
|||
- 9191:9191
|
||||
volumes:
|
||||
- ./data:/data
|
||||
#- ./certs:/certs:ro # TLS certificates (optional)
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
|
|
@ -33,15 +34,26 @@ services:
|
|||
- POSTGRES_DB=dispatcharr
|
||||
- POSTGRES_USER=dispatch
|
||||
- POSTGRES_PASSWORD=secret
|
||||
# PostgreSQL TLS (optional) — mount certs via the volume above
|
||||
#- POSTGRES_SSL=true # required to enable TLS
|
||||
#- POSTGRES_SSL_MODE=verify-full # optional: verify-full (default) | verify-ca | require
|
||||
#- POSTGRES_SSL_CA_CERT=/certs/postgres/ca.crt # optional: CA cert to verify the server
|
||||
#- POSTGRES_SSL_CERT=/certs/postgres/client.crt # optional: client cert (only if server requires client auth)
|
||||
#- POSTGRES_SSL_KEY=/certs/postgres/client.key # optional: client key (only if server requires client auth)
|
||||
|
||||
# Redis Connection
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
|
||||
# Redis Authentication (Optional)
|
||||
# Uncomment and set if your Redis requires authentication:
|
||||
#- REDIS_PASSWORD=your_strong_redis_password
|
||||
#- REDIS_USER=your_redis_username # For Redis 6+ ACL - see Redis service below
|
||||
# Redis TLS (optional) — mount certs via the volume above
|
||||
#- REDIS_SSL=true # required to enable TLS
|
||||
#- REDIS_SSL_VERIFY=true # optional: set false for self-signed certs without a CA
|
||||
#- REDIS_SSL_CA_CERT=/certs/redis/ca.crt # optional: CA cert to verify the server
|
||||
#- REDIS_SSL_CERT=/certs/redis/client.crt # optional: client cert (only if server requires client auth)
|
||||
#- REDIS_SSL_KEY=/certs/redis/client.key # optional: client key (only if server requires client auth)
|
||||
|
||||
# Logging
|
||||
- DISPATCHARR_LOG_LEVEL=info
|
||||
|
|
@ -95,6 +107,7 @@ services:
|
|||
condition: service_started
|
||||
volumes:
|
||||
- ./data:/data
|
||||
#- ./certs:/certs:ro # TLS certificates (optional)
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
entrypoint: ["/app/docker/entrypoint.celery.sh"]
|
||||
|
|
@ -108,21 +121,30 @@ services:
|
|||
# Must match the web service port for DVR recording and internal API calls
|
||||
- DISPATCHARR_PORT=9191
|
||||
|
||||
# PostgreSQL Connection
|
||||
# PostgreSQL — must match web service settings
|
||||
- POSTGRES_HOST=db
|
||||
- POSTGRES_PORT=5432
|
||||
- POSTGRES_DB=dispatcharr
|
||||
- POSTGRES_USER=dispatch
|
||||
- POSTGRES_PASSWORD=secret
|
||||
# PostgreSQL TLS — must match web service
|
||||
#- POSTGRES_SSL=true
|
||||
#- POSTGRES_SSL_MODE=verify-full
|
||||
#- POSTGRES_SSL_CA_CERT=/certs/postgres/ca.crt
|
||||
#- POSTGRES_SSL_CERT=/certs/postgres/client.crt
|
||||
#- POSTGRES_SSL_KEY=/certs/postgres/client.key
|
||||
|
||||
# Redis Connection
|
||||
# Redis — must match web service settings
|
||||
- REDIS_HOST=redis
|
||||
- REDIS_PORT=6379
|
||||
|
||||
# Redis Authentication (Optional)
|
||||
# Uncomment and set if your Redis requires authentication:
|
||||
#- REDIS_PASSWORD=your_strong_redis_password
|
||||
#- REDIS_USER=your_redis_username # For Redis 6+ ACL - see Redis service below
|
||||
#- REDIS_USER=your_redis_username
|
||||
# Redis TLS — must match web service
|
||||
#- REDIS_SSL=true
|
||||
#- REDIS_SSL_VERIFY=true
|
||||
#- REDIS_SSL_CA_CERT=/certs/redis/ca.crt
|
||||
#- REDIS_SSL_CERT=/certs/redis/client.crt
|
||||
#- REDIS_SSL_KEY=/certs/redis/client.key
|
||||
|
||||
# Logging
|
||||
- DISPATCHARR_LOG_LEVEL=info
|
||||
|
|
|
|||
|
|
@ -36,6 +36,23 @@ if [ "$USE_LEGACY_NUMPY" = "true" ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Fix TLS client key permissions for PostgreSQL (same issue as web entrypoint).
|
||||
# libpq requires 0600 but Docker Desktop mounts files as 0777.
|
||||
if [ -n "${POSTGRES_SSL_KEY:-}" ] && [ -f "$POSTGRES_SSL_KEY" ]; then
|
||||
_key_perms=$(stat -c '%a' "$POSTGRES_SSL_KEY" 2>/dev/null)
|
||||
if [ "$_key_perms" != "600" ] && [ "$_key_perms" != "640" ]; then
|
||||
_fixed_key="/data/.pg-client-celery.key"
|
||||
cp "$POSTGRES_SSL_KEY" "$_fixed_key"
|
||||
chmod 600 "$_fixed_key"
|
||||
# Match ownership to the user running Celery if running as root
|
||||
if [ "$(id -u)" = "0" ] && [ -n "${PUID:-}" ]; then
|
||||
chown "${PUID}:${PGID:-$PUID}" "$_fixed_key"
|
||||
fi
|
||||
export POSTGRES_SSL_KEY="$_fixed_key"
|
||||
echo "Fixed PostgreSQL client key permissions (${_key_perms} → 600)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 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)
|
||||
|
|
|
|||
|
|
@ -112,6 +112,14 @@ variables=(
|
|||
CELERY_NICE_LEVEL UWSGI_NICE_LEVEL DJANGO_SECRET_KEY
|
||||
)
|
||||
|
||||
# TLS variables are optional — only propagate when set to avoid noisy warnings
|
||||
for _tls_var in POSTGRES_SSL POSTGRES_SSL_MODE POSTGRES_SSL_CA_CERT POSTGRES_SSL_CERT POSTGRES_SSL_KEY \
|
||||
REDIS_SSL REDIS_SSL_VERIFY REDIS_SSL_CA_CERT REDIS_SSL_CERT REDIS_SSL_KEY; do
|
||||
if [ -n "${!_tls_var+x}" ]; then
|
||||
variables+=("$_tls_var")
|
||||
fi
|
||||
done
|
||||
|
||||
# Truncate files before rewriting
|
||||
> /etc/profile.d/dispatcharr.sh
|
||||
|
||||
|
|
@ -229,6 +237,28 @@ if [ "$USE_LEGACY_NUMPY" = "true" ]; then
|
|||
fi
|
||||
fi
|
||||
|
||||
# Fix TLS client key permissions for PostgreSQL.
|
||||
# libpq requires the client key to be 0600 or stricter. Volume-mounted files
|
||||
# from Windows/macOS hosts often have 0755 permissions, so copy the key to a
|
||||
# writable location with correct permissions if needed.
|
||||
if [ -n "${POSTGRES_SSL_KEY:-}" ] && [ -f "$POSTGRES_SSL_KEY" ]; then
|
||||
_key_perms=$(stat -c '%a' "$POSTGRES_SSL_KEY" 2>/dev/null)
|
||||
if [ "$_key_perms" != "600" ] && [ "$_key_perms" != "640" ]; then
|
||||
_fixed_key="/data/.pg-client.key"
|
||||
cp "$POSTGRES_SSL_KEY" "$_fixed_key"
|
||||
chmod 600 "$_fixed_key"
|
||||
if [ "$(id -u)" = "0" ] && [ -n "${PUID:-}" ]; then
|
||||
chown "${PUID}:${PGID}" "$_fixed_key"
|
||||
fi
|
||||
export POSTGRES_SSL_KEY="$_fixed_key"
|
||||
# Update /etc/environment so login shells see the fixed path
|
||||
sed -i "/^POSTGRES_SSL_KEY=/d" /etc/environment
|
||||
echo "POSTGRES_SSL_KEY='$_fixed_key'" >> /etc/environment
|
||||
sed -i "s|export POSTGRES_SSL_KEY=.*|export POSTGRES_SSL_KEY='$_fixed_key'|" /etc/profile.d/dispatcharr.sh
|
||||
echo "Fixed PostgreSQL client key permissions (${_key_perms} → 600)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run Django commands as non-root user to prevent permission issues
|
||||
su - "$POSTGRES_USER" -c "cd /app && python manage.py migrate --noinput"
|
||||
su - "$POSTGRES_USER" -c "cd /app && python manage.py collectstatic --noinput"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue