Skip to content

fix: optional Postgres via compose-with-db overlay - #276

Open
zdrapela wants to merge 4 commits into
docs/pg16-to-pg18-upgradefrom
fix/RHDHBUGS-1865-compose-with-db
Open

fix: optional Postgres via compose-with-db overlay#276
zdrapela wants to merge 4 commits into
docs/pg16-to-pg18-upgradefrom
fix/RHDHBUGS-1865-compose-with-db

Conversation

@zdrapela

@zdrapela zdrapela commented Jul 27, 2026

Copy link
Copy Markdown
Member

Description

Fixes RHDHBUGS-1865: enabling the optional PostgreSQL service no longer requires uncommenting blocks in the default compose.yaml (which caused merge conflicts on pull).

  • Add compose-with-db.yaml overlay (same pattern as compose-with-corporate-proxy.yaml / compose-dynamic-plugins-root.yaml)
  • Point compose.yaml at the overlay instead of a commented db service
  • Update the PostgreSQL guide for -f compose.yaml -f compose-with-db.yaml, including a combined example with compose-with-corporate-proxy.yaml
  • Major upgrades use temporary gitignored compose.override.yaml + POSTGRES_IMAGE (do not edit tracked compose-with-db.yaml)

Stacked on #278 (docs/pg16-to-pg18-upgrade) — GitHub stack #279. Retarget to main after #278 merges (or merge via gh stack merge).

Which issue(s) does this PR fix or relate to

PR acceptance criteria

  • Tests updated and passing
  • Documentation updated
  • Built-in TechDocs updated if needed. Note that TechDocs changes may need to be reviewed by a Product Manager and/or Architect to ensure content accuracy, clarity, and alignment with user needs.

How to test changes / Special notes to the reviewer

  1. Do not edit compose.yaml for Postgres
  2. podman login registry.redhat.io
  3. Copy POSTGRES_* into .env; switch app-config.local.yaml from SQLite to pg as in the guide
  4. podman compose -f compose.yaml -f compose-with-db.yaml up -ddb healthy, RHDH up
  5. Optional: podman compose -f compose.yaml -f compose-with-db.yaml -f compose-with-corporate-proxy.yaml config merges db + proxy + rhdh.depends_on
  6. npx --yes dclint compose-with-db.yaml → 0 errors

@zdrapela

zdrapela commented Aug 3, 2026

Copy link
Copy Markdown
Member Author

Linked into GitHub stack #279 with gh stack: #278 (bottom) → #276 (top). Note: the previous bottom PR #275 was closed because stacks cannot include fork PRs; #278 is the same commits from redhat-developer:docs/pg16-to-pg18-upgrade.

Avoid editing tracked compose.yaml for PostgreSQL by adding a
compose-with-db.yaml merge file, matching other optional overlays.
Pin db image via POSTGRES_IMAGE and keep temporary POSTGRESQL_UPGRADE
in a gitignored override so users never edit tracked compose-with-db.yaml.
@zdrapela
zdrapela force-pushed the fix/RHDHBUGS-1865-compose-with-db branch from 017de44 to 1432f89 Compare August 3, 2026 09:03
@zdrapela
zdrapela marked this pull request as ready for review August 3, 2026 09:23
@rhdh-qodo-merge

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Fix optional Postgres setup using a compose-with-db overlay

🐞 Bug fix 📝 Documentation ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add a dedicated Compose overlay to enable PostgreSQL without editing the default compose.yaml.
• Switch Postgres enablement to a multi-file compose merge pattern (consistent with other overlays).
• Update PostgreSQL docs to use -f compose.yaml -f compose-with-db.yaml, including upgrade workflow.
Diagram

graph TD
  cmd["podman|docker compose -f ..."] --> c0["compose.yaml"] --> merged["Merged Compose config"] --> rhdh(["rhdh service"]) --> db[("Postgres db")]
  cmd --> cdb["compose-with-db.yaml"] --> merged
  cmd --> covr["compose.override.yaml (gitignored)"] --> merged
  env["default.env + .env"] --> cdb

  subgraph Legend
    direction LR
    _cmd["Command"] ~~~ _file["Compose / env file"] ~~~ _svc(["Service"]) ~~~ _db[("Database")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use Compose profiles (e.g., db enabled via --profile)
  • ➕ Native feature for optional services; avoids managing multiple -f overlays
  • ➕ Keeps all configuration in a single tracked compose.yaml
  • ➖ Still tends to concentrate optional config in one file, increasing merge-conflict risk
  • ➖ Profile behavior and documentation can vary between compose implementations (docker vs podman compose)
2. Maintain the commented db block in compose.yaml
  • ➕ Simplest mental model: one file contains everything
  • ➖ Encourages editing tracked compose.yaml, which is exactly the source of merge conflicts
  • ➖ Harder to compose with other optional overlays cleanly

Recommendation: The overlay approach in this PR is the best fit: it matches existing repo patterns (corporate-proxy, dynamic plugins), avoids tracked-file edits that cause conflicts, and composes cleanly with other overlays. Compose profiles were considered, but overlays provide clearer, tool-agnostic guidance for docker/podman compose and keep optional concerns isolated.

Files changed (5) +85 / -65

Documentation (1) +31 / -42
postgresql-guide.mdUpdate Postgres guide to use compose overlays and safer upgrade steps +31/-42

Update Postgres guide to use compose overlays and safer upgrade steps

• Reworks the setup instructions to start Postgres via '-f compose.yaml -f compose-with-db.yaml', including an example combined with the corporate proxy overlay. Updates major upgrade instructions to use '.env' + a temporary gitignored 'compose.override.yaml' and clarifies that overrides are not auto-loaded when using '-f' overlays.

docs/rhdh-local-guide/postgresql-guide.md

Other (4) +54 / -23
compose-with-db.yamlAdd Postgres overlay with db service and rhdh health dependency +32/-0

Add Postgres overlay with db service and rhdh health dependency

• Introduces a standalone overlay Compose file that adds a PostgreSQL 'db' service and makes 'rhdh' wait for it via 'depends_on' with 'service_healthy'. Allows pinning the image through 'POSTGRES_IMAGE' while keeping a sensible default image.

compose-with-db.yaml

compose.postgres-upgrade.override.example.yamlProvide gitignored override example for one-time major upgrades +18/-0

Provide gitignored override example for one-time major upgrades

• Adds an example override file users can copy to 'compose.override.yaml' to enable 'POSTGRESQL_UPGRADE=copy' for a single boot during major upgrades. Documents that 'compose.override.yaml' must be explicitly included when using multiple '-f' overlays.

compose.postgres-upgrade.override.example.yaml

compose.yamlRemove commented db block and reference the new db overlay +2/-23

Remove commented db block and reference the new db overlay

• Deletes the previously commented-out 'db' service and commented 'depends_on' entries. Replaces them with brief instructions pointing users to merge 'compose-with-db.yaml' when Postgres is desired.

compose.yaml

default.envDocument optional POSTGRES_IMAGE for the db overlay +2/-0

Document optional POSTGRES_IMAGE for the db overlay

• Adds commented guidance for 'POSTGRES_IMAGE' so users can pin the Postgres image used by 'compose-with-db.yaml' without editing tracked Compose files.

default.env

@rhdh-qodo-merge

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Context used
⚠️ Tickets: not configured — ticket URL found in PR but could not be fetched — check ticket provider credentials
✅ Cross-repo context
  Not relevant to this PR: redhat-developer/rhdh
  Not relevant to this PR: redhat-developer/rhdh-plugins

Grey Divider


Action required

1. DB admin password unset 🐞 Bug ≡ Correctness
Description
compose-with-db.yaml sets POSTGRESQL_ADMIN_PASSWORD from ${POSTGRES_PASSWORD}, but
POSTGRES_PASSWORD is only provided via env_file while ./.env is optional; if the user hasn’t
also defined POSTGRES_PASSWORD in the host env/.env at Compose render time, the db gets an empty
admin password and can fail to initialize or authenticate as expected. The same pattern is repeated
in compose.postgres-upgrade.override.example.yaml, so the upgrade flow can fail for the same
reason.
Code

compose-with-db.yaml[R21-22]

+    environment:
+      - POSTGRESQL_ADMIN_PASSWORD=${POSTGRES_PASSWORD}
Relevance

●● Moderate

Same interpolation pattern existed before, but no history discussing env_file vs ${VAR} render-time
pitfalls.

PR-#35
PR-#95

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The overlay marks .env as optional but still uses ${POSTGRES_PASSWORD} interpolation for
POSTGRESQL_ADMIN_PASSWORD, while POSTGRES_PASSWORD is only defined in default.env (an
env_file). The upgrade override repeats the same interpolation, so the upgrade path inherits the
same failure mode.

compose-with-db.yaml[16-22]
default.env[1-8]
compose.postgres-upgrade.override.example.yaml[14-18]
docs/rhdh-local-guide/postgresql-guide.md[10-22]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`POSTGRESQL_ADMIN_PASSWORD` is currently set via Compose interpolation from `${POSTGRES_PASSWORD}`. This can expand to an empty string unless `POSTGRES_PASSWORD` exists in the host environment or the project `.env` at config-render time; values from a service `env_file` are not a reliable source for Compose interpolation.

## Issue Context
- `POSTGRES_PASSWORD` is defined in `default.env`, but `default.env` is only passed into containers via `env_file`.
- `./.env` is optional in the overlay.
- The Postgres image expects `POSTGRESQL_ADMIN_PASSWORD` to be set correctly.

## Fix Focus Areas
- compose-with-db.yaml[16-23]
- compose.postgres-upgrade.override.example.yaml[14-18]
- default.env[1-8]

Suggested implementation direction (pick one):
1) Add `POSTGRESQL_ADMIN_PASSWORD=...` to `default.env` (and let users override in `.env`), then remove the `environment: POSTGRESQL_ADMIN_PASSWORD=...` line from both compose files.
2) If keeping Compose interpolation, at least provide a safe default: `POSTGRESQL_ADMIN_PASSWORD=${POSTGRES_PASSWORD:-postgres}` (and ensure the upgrade override doesn’t reintroduce the empty expansion).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Anonymous DB volume orphaning 🐞 Bug ☼ Reliability
Description
The db service mounts only /var/lib/pgsql/data (no named volume), which creates an anonymous
volume; when the db container is recreated, it may attach a new empty anonymous volume rather than
the previous one, making the database appear “reset” and leaving the old data stranded in an
orphaned volume. This conflicts with the upgrade docs’ assumption that recreating db will reliably
continue using the existing data volume under /var/lib/pgsql/data.
Code

compose-with-db.yaml[R14-15]

+    volumes:
+      - "/var/lib/pgsql/data"
Relevance

● Weak

Repo previously used same anonymous /var/lib/pgsql/data mount in compose.yaml db block without
change.

PR-#95
PR-#35

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The overlay defines the data mount using only a container path (anonymous volume). The upgrade guide
relies on the data staying on the mounted volume across container recreation/upgrade steps, which is
more reliable when the volume is explicitly named.

compose-with-db.yaml[13-16]
docs/rhdh-local-guide/postgresql-guide.md[102-115]
docs/rhdh-local-guide/postgresql-guide.md[132-148]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The Postgres data directory is currently mounted using anonymous volume syntax (`- "/var/lib/pgsql/data"`). Anonymous volumes are not predictably reusable/attachable across container recreation, which is risky for persistence and for the documented major-upgrade flow.

## Issue Context
The docs instruct users to recreate the `db` container while keeping the existing data volume. That expectation is much safer when the data volume is explicitly named.

## Fix Focus Areas
- compose-with-db.yaml[13-16]
- docs/rhdh-local-guide/postgresql-guide.md[102-115]

Suggested implementation direction:
- Change the db mount to a named volume, e.g. `postgres-data:/var/lib/pgsql/data`.
- Add a top-level `volumes:` entry in the overlay (`postgres-data:`). (Compose will merge top-level volumes with `compose.yaml`.)
- Optionally update the docs to mention the named volume so users can identify it if troubleshooting.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added documentation Improvements or additions to documentation enhancement New feature or request Bug fix labels Aug 3, 2026
@sonarqubecloud

sonarqubecloud Bot commented Aug 3, 2026

Copy link
Copy Markdown

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

Labels

Bug fix documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant