Skip to content

Conversation

@rajadilipkolli
Copy link
Owner

@rajadilipkolli rajadilipkolli commented Aug 31, 2025

Summary by CodeRabbit

  • New Features

    • Added a local PostgreSQL read-replica stack (master, replica, pgAdmin) with init and bootstrap scripts.
    • Enforced UTC at app startup and applied UTC to primary and replica datasource settings.
    • Added a VS Code launch configuration for the read-replica app.
  • Chores

    • CI updated to explicitly reference the compose file path.
    • Replaced legacy compose layout with a reorganized compose setup and supporting scripts.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 31, 2025

Walkthrough

Adds a Docker-based PostgreSQL read-replica setup and scripts, removes an older compose file, updates CI to reference the new compose path, adds a VSCode Java launch config, forces JVM timezone to UTC at startup, and appends UTC params to datasource URLs.

Changes

Cohort / File(s) Summary
CI workflow compose selection
.github/workflows/jpa-boot-read-replica-postgresql.yml
Docker Compose invocation changed to explicitly pass the compose file via -f docker/docker-compose.yml in the "Start up databases via docker compose" step; other step commands unchanged.
Editor tooling
.vscode/launch.json
Adds Java launch configuration Spring Boot-ReadReplicaApplication<boot-read-replica-postgresql> pointing to com.example.demo.readreplica.ReadReplicaApplication with envFile: ${workspaceFolder}/.env.
Docker compose — new
jpa/boot-read-replica-postgresql/docker/docker-compose.yml
Adds compose defining postgresql-master, postgresql-slave, and pgadmin4 services plus postgresql_master_data and postgresql_slave_data volumes, healthchecks, slave entrypoint, and volume-mounted init/config scripts.
Docker compose — removed (old)
jpa/boot-read-replica-postgresql/docker-compose.yaml
Deletes previous compose that defined Bitnami master/slave and pgAdmin4.
DB init and replication scripts
jpa/boot-read-replica-postgresql/docker/init-master.sql, jpa/boot-read-replica-postgresql/docker/configure-master.sh, jpa/boot-read-replica-postgresql/docker/setup-slave.sh
Adds master init SQL to create replication user and grants; adds master config script to enable WAL/replication settings; adds slave setup script to wait for master, perform pg_basebackup (or reuse data dir), configure standby, and start replica.
Application bootstrap
jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java
Sets default timezone to UTC via TimeZone.setDefault(...) and System.setProperty("user.timezone","UTC") before SpringApplication.run.
Application configuration
jpa/boot-read-replica-postgresql/src/main/resources/application.yml
Appends ?TimeZone=UTC&serverTimezone=UTC to primary and replica JDBC URLs and adds Hikari serverTimezone: UTC datasource properties for both datasources.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CI as CI
  participant DC as Docker Compose
  participant M as postgresql-master
  participant S as postgresql-slave
  participant PG as pgAdmin4
  participant App as Spring Boot App

  CI->>DC: docker compose -f docker/docker-compose.yml up
  DC->>M: start postgres:17 (mount init-master.sql & configure-master.sh)
  DC->>PG: start pgAdmin4
  DC->>S: start postgres:17 (entrypoint /setup-slave.sh)

  rect rgb(220,240,255)
    M->>M: run init SQL (create repl user) + configure-master.sh (enable WAL/replication)
  end

  rect rgb(255,245,220)
    S->>M: wait until master healthy
    alt PGDATA empty
      S->>M: pg_basebackup (replication user) -> populate PGDATA
      S->>S: configure standby (hot_standby, permissions)
    else PGDATA exists
      S->>S: ensure ownership & standby settings
    end
    S->>S: start PostgreSQL in standby mode
  end

  App->>M: connect primary JDBC (with UTC params)
  App->>S: connect replica JDBC (with UTC params)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I nudged the compose, watched containers spin,
Master hummed WAL while the little slave chimed in.
UTC stitched through each JDBC line,
Scripts set replication, all ready in time.
Hooray — a rabbit hop for sync so fine! 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore : switch to official postgres" is directly related to the primary change in the pull request, which is migrating the Docker-based PostgreSQL infrastructure from Bitnami images (bitnami/postgresql:latest) to the official PostgreSQL image (postgres:17). This migration is the architectural change that necessitates all other modifications in the changeset, including the restructuring of docker-compose files, addition of initialization and setup scripts, and configuration updates. The title is specific enough to convey meaningful information about the changeset without being vague, and a teammate reviewing the commit history would clearly understand that the main focus is switching to official PostgreSQL images.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch postgres-slave

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6edf8c4 and f67da9e.

📒 Files selected for processing (1)
  • .github/workflows/jpa-boot-read-replica-postgresql.yml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/jpa-boot-read-replica-postgresql.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (13)
jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java (1)

11-13: Set timezone via JVM args; avoid runtime System.setProperty.

Setting user.timezone at runtime is brittle. Keep TimeZone.setDefault(...) or pass -Duser.timezone=UTC in launch/CI. Remove the System.setProperty line.

-        System.setProperty("user.timezone", "UTC");
jpa/boot-read-replica-postgresql/src/main/resources/application.yml (1)

23-23: Normalize Hikari property naming.

Use either pool-name or poolName consistently. Spring’s binder handles both, but consistency helps.

-        poolName: replicaHikariPool
+        pool-name: replicaHikariPool
jpa/boot-read-replica-postgresql/docker/configure-master.sh (2)

2-2: Harden script options.

Use -euo pipefail for safer bash.

-set -e
+set -euo pipefail

10-15: Optional: move standby-only settings to the replica.

hot_standby and hot_standby_feedback are only effective on standbys. Keep here for simplicity, but ideally set them in the replica’s config.

jpa/boot-read-replica-postgresql/docker/init-master.sql (1)

10-18: Tighten comments; actual pg_hba changes are done in shell script.

Simplify to avoid confusion.

--- Update pg_hba.conf to allow replication connections
--- This will be added to the end of pg_hba.conf by PostgreSQL init process
-DO $$
-BEGIN
-    -- Add replication entry to pg_hba.conf
-    -- Note: The official postgres image handles pg_hba.conf configuration
-    -- The replication connection will be allowed via the default settings
-    RAISE NOTICE 'Replication user created successfully';
-END $$;
+DO $$
+BEGIN
+    RAISE NOTICE 'Replication user created successfully';
+END $$;
.vscode/launch.json (1)

296-305: Add UTC JVM arg for consistency with runtime timezone policy.

This keeps dev runs aligned without relying on in-code System.setProperty.

         {
             "type": "java",
             "name": "Spring Boot-ReadReplicaApplication<boot-read-replica-postgresql>",
             "request": "launch",
             "cwd": "${workspaceFolder}",
             "mainClass": "com.example.demo.readreplica.ReadReplicaApplication",
             "projectName": "boot-read-replica-postgresql",
             "args": "",
-            "envFile": "${workspaceFolder}/.env"
+            "envFile": "${workspaceFolder}/.env",
+            "vmArgs": "-Duser.timezone=UTC"
         }
jpa/boot-read-replica-postgresql/docker/setup-slave.sh (3)

2-2: Stricter bash safety flags.

-set -e
+set -Eeuo pipefail

8-14: Parameterize DB name and add a connect timeout.

Hardcoding my_database can fail if renamed. Default to ${POSTGRES_DB:-postgres} and ensure quick retries.

-echo "Waiting for master to be ready..."
-until PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_MASTER_HOST" -p "$POSTGRES_MASTER_PORT" -U "$POSTGRES_USER" -d "my_database" -c '\l' > /dev/null 2>&1
+echo "Waiting for master to be ready..."
+export PGCONNECT_TIMEOUT=${PGCONNECT_TIMEOUT:-5}
+DB_TO_CHECK="${POSTGRES_DB:-postgres}"
+until PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$POSTGRES_MASTER_HOST" -p "$POSTGRES_MASTER_PORT" -U "$POSTGRES_USER" -d "$DB_TO_CHECK" -c '\l' > /dev/null 2>&1
 do
   echo "Waiting for master database..."
   sleep 3
 done

41-45: Avoid mixing config-file edits with -c flags (consistency).

You already append hot_standby settings; relying on postgresql.conf in both branches avoids surprises.

Apply the earlier -D fix and consider removing the -c overrides in Line 22 for consistency.

jpa/boot-read-replica-postgresql/docker/docker-compose.yml (4)

25-25: Fix trailing whitespace (yamllint).


9-10: Mount init scripts read-only.

Avoid accidental in-container edits.

-      - './init-master.sql:/docker-entrypoint-initdb.d/01-init-master.sql'
-      - './configure-master.sh:/docker-entrypoint-initdb.d/02-configure-master.sh'
+      - './init-master.sql:/docker-entrypoint-initdb.d/01-init-master.sql:ro'
+      - './configure-master.sh:/docker-entrypoint-initdb.d/02-configure-master.sh:ro'

48-48: Add newline at EOF (yamllint).


34-43: Consider using a less-common default for pgAdmin credentials in public repos.

Even in dev, “admin/admin” variants propagate into demos. Optional hardening.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e934eec and 45a80e1.

📒 Files selected for processing (9)
  • .github/workflows/jpa-boot-read-replica-postgresql.yml (1 hunks)
  • .vscode/launch.json (1 hunks)
  • jpa/boot-read-replica-postgresql/docker-compose.yaml (0 hunks)
  • jpa/boot-read-replica-postgresql/docker/configure-master.sh (1 hunks)
  • jpa/boot-read-replica-postgresql/docker/docker-compose.yml (1 hunks)
  • jpa/boot-read-replica-postgresql/docker/init-master.sql (1 hunks)
  • jpa/boot-read-replica-postgresql/docker/setup-slave.sh (1 hunks)
  • jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java (1 hunks)
  • jpa/boot-read-replica-postgresql/src/main/resources/application.yml (1 hunks)
💤 Files with no reviewable changes (1)
  • jpa/boot-read-replica-postgresql/docker-compose.yaml
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: rajadilipkolli
PR: rajadilipkolli/my-spring-boot-experiments#0
File: :0-0
Timestamp: 2025-01-16T03:40:40.079Z
Learning: The boot-data-multipledatasources module demonstrates multiple datasource configuration with PostgreSQL (using Liquibase) and MySQL (using Flyway) databases, implementing parallel data fetching using CompletableFuture with a 5-second timeout.
📚 Learning: 2025-01-16T03:40:40.079Z
Learnt from: rajadilipkolli
PR: rajadilipkolli/my-spring-boot-experiments#0
File: :0-0
Timestamp: 2025-01-16T03:40:40.079Z
Learning: The boot-data-multipledatasources module demonstrates multiple datasource configuration with PostgreSQL (using Liquibase) and MySQL (using Flyway) databases, implementing parallel data fetching using CompletableFuture with a 5-second timeout.

Applied to files:

  • jpa/boot-read-replica-postgresql/src/main/resources/application.yml
🪛 YAMLlint (1.37.1)
jpa/boot-read-replica-postgresql/docker/docker-compose.yml

[error] 25-25: trailing spaces

(trailing-spaces)


[error] 48-48: no new line character at the end of file

(new-line-at-end-of-file)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
jpa/boot-read-replica-postgresql/src/main/java/com/example/demo/readreplica/ReadReplicaApplication.java (1)

3-3: LGTM on import.

jpa/boot-read-replica-postgresql/docker/setup-slave.sh (1)

1-50: Confirm gosu availability and script exec bit.

Ensure gosu exists in postgres:17 image (it does in official) and the repo preserves +x on this script so the container can run it.

Would you like a quick checklist or a pre-flight CI step to assert both?

Comment on lines 35 to 39
run: |
docker compose up -d postgresql-master postgresql-slave
docker compose -f docker/docker-compose.yml up -d postgresql-master postgresql-slave
sleep 5
docker ps -a
- name: Build and analyze
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use healthchecks and --wait to deflake CI; drop arbitrary sleep.

Rely on Compose health status rather than sleep 5.

-          docker compose -f docker/docker-compose.yml up -d postgresql-master postgresql-slave
-          sleep 5
+          docker compose -f docker/docker-compose.yml up -d --wait
           docker ps -a

Follow-up: add healthchecks in the compose file (see next comment).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run: |
docker compose up -d postgresql-master postgresql-slave
docker compose -f docker/docker-compose.yml up -d postgresql-master postgresql-slave
sleep 5
docker ps -a
- name: Build and analyze
run: |
docker compose -f docker/docker-compose.yml up -d --wait
docker ps -a
🤖 Prompt for AI Agents
.github/workflows/jpa-boot-read-replica-postgresql.yml lines 35-39: the workflow
uses a fixed sleep to wait for DBs which flakes; replace the arbitrary sleep
with compose health-based waiting and remove the sleep. Update the `docker
compose` invocation to use the built-in wait behavior (e.g. `docker compose up
-d --wait` or `docker compose up -d` followed by a compose wait/health-check
loop) so the step blocks until postgresql-master and postgresql-slave are
healthy, and ensure the docker-compose.yml defines proper healthchecks for those
services; drop `sleep 5` and add a sensible timeout/fail behavior if services
don’t become healthy.

Comment on lines +7 to +16
cat >> "$PGDATA/postgresql.conf" <<EOF
# Replication settings
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
hot_standby = on
hot_standby_feedback = on
listen_addresses = '*'
EOF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add essential PG settings for modern auth and dev replication.

Ensure SCRAM and retain WAL for short outages.

 cat >> "$PGDATA/postgresql.conf" <<EOF
 
 # Replication settings
 wal_level = replica
 max_wal_senders = 3
 max_replication_slots = 3
 hot_standby = on
 hot_standby_feedback = on
 listen_addresses = '*'
+password_encryption = scram-sha-256
+wal_keep_size = 64MB
 EOF
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cat >> "$PGDATA/postgresql.conf" <<EOF
# Replication settings
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
hot_standby = on
hot_standby_feedback = on
listen_addresses = '*'
EOF
cat >> "$PGDATA/postgresql.conf" <<EOF
# Replication settings
wal_level = replica
max_wal_senders = 3
max_replication_slots = 3
hot_standby = on
hot_standby_feedback = on
listen_addresses = '*'
password_encryption = scram-sha-256
wal_keep_size = 64MB
EOF
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/configure-master.sh around lines 7 to
16, the generated postgresql.conf lacks modern auth and WAL-retention settings;
update the appended block to set password_encryption = 'scram-sha-256' to enable
SCRAM authentication and add a small WAL retention like wal_keep_size = 64MB (or
a size appropriate for your outage window) so standby replicas can catch up
after short outages; keep the existing replication settings and ensure these two
lines are added to the same heredoc so they are written into postgresql.conf.

Comment on lines +19 to +23
cat >> "$PGDATA/pg_hba.conf" <<EOF
# Replication connections
host replication repl_user 0.0.0.0/0 md5
EOF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use SCRAM and avoid world-open CIDR for replication access.

md5 will fail if users are stored with SCRAM (default in newer Postgres). Also, 0.0.0.0/0 is unnecessarily broad; restrict to your Docker network or make it configurable.

 cat >> "$PGDATA/pg_hba.conf" <<EOF
 
 # Replication connections
-host replication repl_user 0.0.0.0/0 md5
+# Prefer a narrowed CIDR (e.g., 172.18.0.0/16) or pass REPLICA_CIDR via env.
+host replication repl_user ${REPLICA_CIDR:-172.18.0.0/16} scram-sha-256
 EOF
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cat >> "$PGDATA/pg_hba.conf" <<EOF
# Replication connections
host replication repl_user 0.0.0.0/0 md5
EOF
cat >> "$PGDATA/pg_hba.conf" <<EOF
# Replication connections
# Prefer a narrowed CIDR (e.g., 172.18.0.0/16) or pass REPLICA_CIDR via env.
host replication repl_user ${REPLICA_CIDR:-172.18.0.0/16} scram-sha-256
EOF
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/configure-master.sh around lines 19
to 23, the pg_hba.conf entry uses "md5" and "0.0.0.0/0"; update it to use
"scram-sha-256" (to match modern Postgres SCRAM password storage) and restrict
the allowed CIDR to a more specific network or a configurable environment
variable (e.g., use an env var like REPL_NETWORK with a sensible default) so
replication access is not world-open; also ensure repl_user is
created/configured to use SCRAM-authenticated password in the setup scripts.

Comment on lines +18 to +23
if [ "$(ls -A $PGDATA 2>/dev/null)" ]; then
echo "Data directory exists, starting PostgreSQL..."
# Change ownership and start as postgres user
chown -R postgres:postgres "$PGDATA"
exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Make the data-dir check robust and quote variables.

ls -A on a non-PG dir can false-positive. Check PG_VERSION instead and quote $PGDATA.

-if [ "$(ls -A $PGDATA 2>/dev/null)" ]; then
+if [ -s "$PGDATA/PG_VERSION" ]; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ "$(ls -A $PGDATA 2>/dev/null)" ]; then
echo "Data directory exists, starting PostgreSQL..."
# Change ownership and start as postgres user
chown -R postgres:postgres "$PGDATA"
exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
else
if [ -s "$PGDATA/PG_VERSION" ]; then
echo "Data directory exists, starting PostgreSQL..."
# Change ownership and start as postgres user
chown -R postgres:postgres "$PGDATA"
exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
else
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/setup-slave.sh around lines 18 to 23,
the current data-dir check using ls -A can return false positives and doesn't
quote variables; replace it with a robust existence check for the PostgreSQL
version file and quote PGDATA. Specifically, test for the presence of
"$PGDATA/PG_VERSION" (e.g. if [ -f "$PGDATA/PG_VERSION" ]; then) and ensure all
references to PGDATA are quoted (e.g. "$PGDATA") before chown and when deciding
to start PostgreSQL.

echo "Data directory exists, starting PostgreSQL..."
# Change ownership and start as postgres user
chown -R postgres:postgres "$PGDATA"
exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Pass data dir explicitly to postgres.

Be explicit with -D "$PGDATA"; relying on environment here is brittle.

-    exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
+    exec gosu postgres postgres -D "$PGDATA" -c hot_standby=on -c hot_standby_feedback=on
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exec gosu postgres postgres -c hot_standby=on -c hot_standby_feedback=on
exec gosu postgres postgres -D "$PGDATA" -c hot_standby=on -c hot_standby_feedback=on
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/setup-slave.sh around line 22, the
postgres invocation should explicitly pass the data directory; replace the
existing exec line with one that adds -D "$PGDATA" before the -c options (i.e.
exec gosu postgres postgres -D "$PGDATA" -c hot_standby=on -c
hot_standby_feedback=on), preserving the existing flags and ensuring PGDATA is
quoted.

Comment on lines +27 to +35
PGPASSWORD="$REPLICATION_PASSWORD" pg_basebackup \
-h "$POSTGRES_MASTER_HOST" \
-p "$POSTGRES_MASTER_PORT" \
-U "$REPLICATION_USER" \
-D "$PGDATA" \
-W \
-v \
-R \
-X stream
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove -W; it forces an interactive password prompt and can hang CI.

pg_basebackup -W ignores PGPASSWORD and demands a TTY; you already export PGPASSWORD. Drop -W.

-        -W \
         -v \
         -R \
         -X stream
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
PGPASSWORD="$REPLICATION_PASSWORD" pg_basebackup \
-h "$POSTGRES_MASTER_HOST" \
-p "$POSTGRES_MASTER_PORT" \
-U "$REPLICATION_USER" \
-D "$PGDATA" \
-W \
-v \
-R \
-X stream
PGPASSWORD="$REPLICATION_PASSWORD" pg_basebackup \
-h "$POSTGRES_MASTER_HOST" \
-p "$POSTGRES_MASTER_PORT" \
-U "$REPLICATION_USER" \
-D "$PGDATA" \
-v \
-R \
-X stream
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/setup-slave.sh around lines 27 to 35,
the pg_basebackup invocation includes the -W flag which forces an interactive
password prompt (ignoring PGPASSWORD) and can hang CI; remove the -W flag from
the command so PGPASSWORD is used non-interactively, and verify PGPASSWORD is
exported or set in the environment before calling pg_basebackup.

EOF

echo "Base backup complete. Starting PostgreSQL in standby mode..."
exec gosu postgres postgres
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Same: start with -D.

-    exec gosu postgres postgres
+    exec gosu postgres postgres -D "$PGDATA"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
exec gosu postgres postgres
exec gosu postgres postgres -D "$PGDATA"
🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/docker/setup-slave.sh around line 48, the
postgres process is started without the data-directory flag; update the exec
line to start the postgres server with the same -D data-directory argument used
elsewhere (e.g., pass -D followed by the PGDATA path variable) so the server
uses the correct data directory when launched under gosu postgres.

username: postgres_write
driverClassName: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/my_database
url: jdbc:postgresql://localhost:5432/my_database?TimeZone=UTC&serverTimezone=UTC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix PostgreSQL timezone configuration; remove MySQL-only serverTimezone.

serverTimezone is a MySQL property and is ignored by the PG driver. Use PG’s options to set the session timezone, or rely on hibernate.jdbc.time_zone + JVM UTC. Update URLs and drop the extraneous data-source-properties.

-      url: jdbc:postgresql://localhost:5432/my_database?TimeZone=UTC&serverTimezone=UTC
+      url: jdbc:postgresql://localhost:5432/my_database?options=-c%20timezone=UTC
@@
-          serverTimezone: UTC
@@
-      url: jdbc:postgresql://localhost:15432/my_database?TimeZone=UTC&serverTimezone=UTC
+      url: jdbc:postgresql://localhost:15432/my_database?options=-c%20timezone=UTC
@@
-        data-source-properties:
-          serverTimezone: UTC
+        data-source-properties: {}

Also applies to: 14-14, 20-20, 24-25

🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/src/main/resources/application.yml around
line 8 (and likewise at 14, 20, and 24-25) the JDBC URL includes the MySQL-only
parameter serverTimezone which the PostgreSQL driver ignores; remove
serverTimezone from the URLs and either add Postgres-compatible session timezone
(e.g. append ?options=-c%20TimeZone=UTC) or rely on hibernate.jdbc.time_zone and
setting the JVM default to UTC, and delete any extraneous data-source-properties
related to MySQL.

💡 Verification agent

🧩 Analysis chain

Verify connectivity rules for host->container access.

If pg_hba.conf doesn’t allow host connections for normal DB access, app connections to localhost:5432/15432 may fail. Ensure pg_hba has a “host all … scram-sha-256” rule for your CIDR on both primary and replica.

Also applies to: 20-20


🏁 Script executed:

#!/bin/bash
# Inspect any pg_hba additions in repo (compose/scripts)
rg -nP "pg_hba\.conf|host\s+all\s+all" -C2

Length of output: 1600


Add host rules for normal DB access in pg_hba.conf
The Docker init scripts only append replication entries. You must also append a host all all <your-CIDR> scram-sha-256 rule to $PGDATA/pg_hba.conf for application connections in both docker/configure-master.sh (and your replica setup) to ensure the app can connect.

🤖 Prompt for AI Agents
In jpa/boot-read-replica-postgresql/src/main/resources/application.yml around
line 8, the Docker init only appends replication entries to pg_hba.conf so
application connections will be rejected; update docker/configure-master.sh (and
your replica setup script) to also append a host rule like "host all all
<YOUR_CIDR> scram-sha-256" to $PGDATA/pg_hba.conf (use a configurable CIDR
variable), ensure the append happens after PGDATA exists, and trigger a Postgres
reload/restart as needed so the new rule takes effect.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
jpa/boot-read-replica-postgresql/docker/docker-compose.yml (3)

15-20: Past suggestion addressed: master healthcheck added correctly.

Health probe via pg_isready looks good and enables compose --wait.


25-27: Past suggestion addressed: slave waits for healthy master.

Using depends_on with condition: service_healthy is the right call.


40-45: Past suggestion addressed: slave healthcheck present and reasonable.

Readiness for the replica is covered.

🧹 Nitpick comments (7)
jpa/boot-read-replica-postgresql/docker/docker-compose.yml (7)

17-20: Make healthchecks more tolerant of first-time init.

Initial cluster init + scripts can exceed current start_period/timeout. Consider slightly looser thresholds to reduce false negatives.

Apply:

-      interval: 5s
-      timeout: 3s
-      retries: 20
-      start_period: 10s
+      interval: 10s
+      timeout: 5s
+      retries: 30
+      start_period: 30s
-      interval: 5s
-      timeout: 3s
-      retries: 20
-      start_period: 15s
+      interval: 10s
+      timeout: 5s
+      retries: 30
+      start_period: 45s

Also applies to: 42-45


51-52: Make pgAdmin depend on a healthy master.

This avoids pgAdmin racing the DB on cold starts.

-    depends_on:
-      - postgresql-master
+    depends_on:
+      postgresql-master:
+        condition: service_healthy

4-6: Add restart policies for smoother local UX.

Ensures services recover from transient failures and after daemon restarts.

   postgresql-master:
     image: 'postgres:17'
+    restart: unless-stopped
     ports:
       - '5432:5432'
@@
   postgresql-slave:
     image: 'postgres:17'
+    restart: unless-stopped
     ports:
       - '15432:5432'
@@
   pgadmin4:
     image: dpage/pgadmin4
+    restart: unless-stopped
     ports:
       - "5050:80"

Also applies to: 22-24, 48-50


5-6: Parameterize host ports to avoid clashes.

Allows overriding without editing the file (helpful if 5432 already in use).

-      - '5432:5432'
+      - '${PG_MASTER_PORT:-5432}:5432'
@@
-      - '15432:5432'
+      - '${PG_REPLICA_PORT:-15432}:5432'

Also applies to: 23-24


31-38: Move dev credentials to an env file (or document clearly as dev-only).

Reduces accidental leaks and eases overrides; keep current values in .env.example.

Example:

-    environment:
-      - POSTGRES_USER=postgres_write
-      - POSTGRES_PASSWORD=postgres_write
-      - POSTGRES_DB=my_database
+    env_file:
+      - .env.postgres

And for pgAdmin:

-    environment:
-      - [email protected]
-      - PGADMIN_DEFAULT_PASSWORD=admin
+    env_file:
+      - .env.pgadmin

Also applies to: 53-55, 11-14


21-39: Consider renaming “slave” to “replica/standby.”

More inclusive and aligns with Postgres docs (“primary/standby,” “publisher/subscriber”). No functional impact.


61-61: Add a newline at EOF.

Fixes YAMLlint warning and keeps diffs cleaner.

-    driver: local
\ No newline at end of file
+    driver: local
+
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 45a80e1 and 3d85663.

📒 Files selected for processing (1)
  • jpa/boot-read-replica-postgresql/docker/docker-compose.yml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
jpa/boot-read-replica-postgresql/docker/docker-compose.yml

[error] 61-61: no new line character at the end of file

(new-line-at-end-of-file)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants