diff --git a/docker-compose.yml b/docker-compose.yml index 1d5cf7b..d3f8bd0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,6 +53,24 @@ services: # CONFIG_ENCRYPTION_KEY: "your-custom-encryption-key-here" # POSTGRES_PASSWORD: "your-custom-postgres-password-here" + # ======================================================================== + # OPTIONAL: External PostgreSQL and Redis + # ======================================================================== + # To use external PostgreSQL or Redis instances instead of the internal ones, + # uncomment and configure the appropriate URL(s): + # + # External PostgreSQL example: + # DATABASE_URL: "postgresql://username:password@postgres.example.com:5432/readmeabook" + # + # External Redis example: + # REDIS_URL: "redis://redis.example.com:6379" + # REDIS_URL: "redis://:password@redis.example.com:6379" # With password + # + # Note: When using external services: + # - The internal PostgreSQL/Redis will NOT start (smart detection) + # - You do NOT need to mount ./pgdata or ./redis volumes + # - Ensure your external services are accessible from the container + # ======================================================================== # OPTIONAL: Rootless Podman Support # ======================================================================== diff --git a/docker/unified/entrypoint.sh b/docker/unified/entrypoint.sh index 4669352..7971ca4 100644 --- a/docker/unified/entrypoint.sh +++ b/docker/unified/entrypoint.sh @@ -157,16 +157,41 @@ export PLEX_PRODUCT_NAME="${PLEX_PRODUCT_NAME:-ReadMeABook}" export LOG_LEVEL="${LOG_LEVEL:-info}" # ============================================================================ -# INITIALIZE POSTGRESQL +# DETECT EXTERNAL SERVICES # ============================================================================ -PGDATA="/var/lib/postgresql/data" -PG_WAS_EMPTY=0 +# Check if user provided external DATABASE_URL or REDIS_URL +USE_EXTERNAL_POSTGRES=false +USE_EXTERNAL_REDIS=false -# Ensure correct ownership of data directories (critical for bind mounts) -echo "🔧 Setting up directory permissions..." +if [ -n "$DATABASE_URL" ]; then + DB_HOST=$(echo "$DATABASE_URL" | sed -n 's|.*@\([^:/]*\).*|\1|p') + if [ "$DB_HOST" != "127.0.0.1" ] && [ "$DB_HOST" != "localhost" ]; then + USE_EXTERNAL_POSTGRES=true + echo "â„šī¸ External PostgreSQL detected at $DB_HOST" + fi +fi -# PostgreSQL directories - owned by postgres user, group accessible -if ! chown -R postgres:postgres "$PGDATA" /var/run/postgresql 2>/dev/null; then +if [ -n "$REDIS_URL" ]; then + REDIS_HOST=$(echo "$REDIS_URL" | sed -n 's|redis://\([^:@]*@\)\?\([^:/]*\).*|\2|p') + if [ "$REDIS_HOST" != "127.0.0.1" ] && [ "$REDIS_HOST" != "localhost" ]; then + USE_EXTERNAL_REDIS=true + echo "â„šī¸ External Redis detected at $REDIS_HOST" + fi +fi + +# ============================================================================ +# INITIALIZE POSTGRESQL (only if using internal PostgreSQL) +# ============================================================================ +if [ "$USE_EXTERNAL_POSTGRES" = "false" ]; then + echo "đŸ“Ļ Configuring internal PostgreSQL..." + PGDATA="/var/lib/postgresql/data" + PG_WAS_EMPTY=0 + + # Ensure correct ownership of data directories (critical for bind mounts) + echo "🔧 Setting up directory permissions..." + + # PostgreSQL directories - owned by postgres user, group accessible + if ! chown -R postgres:postgres "$PGDATA" /var/run/postgresql 2>/dev/null; then echo "" echo "❌ ERROR: Failed to set ownership on PostgreSQL directories" echo "" @@ -194,30 +219,37 @@ if ! chown -R postgres:postgres "$PGDATA" /var/run/postgresql 2>/dev/null; then echo " 3. Pre-create directories with correct ownership:" echo " mkdir -p pgdata redis config cache" echo " # Let Docker create them on first run" - echo "" - exit 1 -fi + echo "" + exit 1 + fi -if [ -n "$PGID" ]; then - # With PUID/PGID: Use 750 (owner rwx, group rx) for PostgreSQL data - # This allows the PGID group to read PostgreSQL files if needed - chmod 750 "$PGDATA" - chmod 775 /var/run/postgresql + if [ -n "$PGID" ]; then + # With PUID/PGID: Use 750 (owner rwx, group rx) for PostgreSQL data + # This allows the PGID group to read PostgreSQL files if needed + chmod 750 "$PGDATA" + chmod 775 /var/run/postgresql + else + # Without PUID/PGID: Use strict 700 permissions (owner only) + chmod 700 "$PGDATA" + chmod 775 /var/run/postgresql + fi else - # Without PUID/PGID: Use strict 700 permissions (owner only) - chmod 700 "$PGDATA" - chmod 775 /var/run/postgresql + echo "â­ī¸ Skipping internal PostgreSQL setup (using external database)" fi # Redis directory - owned by redis user (remapped to PUID:PGID if set) -if ! chown -R redis:redis /var/lib/redis 2>/dev/null; then - echo "" - echo "❌ ERROR: Failed to set ownership on Redis directory" - echo " See solutions above for PostgreSQL directories" - echo "" - exit 1 +if [ "$USE_EXTERNAL_REDIS" = "false" ]; then + if ! chown -R redis:redis /var/lib/redis 2>/dev/null; then + echo "" + echo "❌ ERROR: Failed to set ownership on Redis directory" + echo " See solutions above for PostgreSQL directories" + echo "" + exit 1 + fi + chmod 770 /var/lib/redis +else + echo "â­ī¸ Skipping internal Redis setup (using external Redis)" fi -chmod 770 /var/lib/redis # App directories - owned by node user (remapped to PUID:PGID if set) # These need group write permissions for shared access @@ -232,18 +264,20 @@ chmod 775 /app/config /app/cache echo "✅ Directory permissions configured" -if [ ! -f "$PGDATA/PG_VERSION" ]; then - PG_WAS_EMPTY=1 - echo "đŸ“Ļ Initializing PostgreSQL database..." - su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA" +if [ "$USE_EXTERNAL_POSTGRES" = "false" ]; then + # Only initialize/setup PostgreSQL if using internal instance + if [ ! -f "$PGDATA/PG_VERSION" ]; then + PG_WAS_EMPTY=1 + echo "đŸ“Ļ Initializing PostgreSQL database..." + su - postgres -c "/usr/lib/postgresql/16/bin/initdb -D $PGDATA" - # Configure PostgreSQL for local access - echo "host all all 127.0.0.1/32 trust" >> "$PGDATA/pg_hba.conf" - echo "host all all ::1/128 trust" >> "$PGDATA/pg_hba.conf" - echo "local all all trust" >> "$PGDATA/pg_hba.conf" + # Configure PostgreSQL for local access + echo "host all all 127.0.0.1/32 trust" >> "$PGDATA/pg_hba.conf" + echo "host all all ::1/128 trust" >> "$PGDATA/pg_hba.conf" + echo "local all all trust" >> "$PGDATA/pg_hba.conf" - # Update postgresql.conf for performance - cat >> "$PGDATA/postgresql.conf" <> "$PGDATA/postgresql.conf" < /dev/null 2>&1; then - echo "✅ PostgreSQL is ready" - break + echo "✅ PostgreSQL initialized" + else + echo "✅ PostgreSQL data directory already exists" fi - echo "âŗ Waiting for PostgreSQL to be ready... ($i/30)" - sleep 1 -done -# Always ensure user and database exist (safe due to IF NOT EXISTS checks) -# This handles cases where data directory exists but user/database don't -echo "👤 Ensuring database user and database exist..." -su - postgres -c "psql -h 127.0.0.1 -U postgres" < /dev/null 2>&1; then + echo "✅ PostgreSQL is ready" + break + fi + echo "âŗ Waiting for PostgreSQL to be ready... ($i/30)" + sleep 1 + done + + # Always ensure user and database exist (safe due to IF NOT EXISTS checks) + # This handles cases where data directory exists but user/database don't + echo "👤 Ensuring database user and database exist..." + su - postgres -c "psql -h 127.0.0.1 -U postgres" <