Skip to content

feat(mail): make mail database port configurable with auto-discovery fallback (fixes #828) - #829

Open
lagmandu wants to merge 1 commit into
oblien:mainfrom
lagmandu:feat/configurable-mail-db-port
Open

lagmandu wants to merge 1 commit into
oblien:mainfrom
lagmandu:feat/configurable-mail-db-port

Conversation

@lagmandu

@lagmandu lagmandu commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Resolves #828 by making the mail database (PostgreSQL sidecar) host loopback port configurable via the OPENSHIP_MAIL_DB_PORT environment variable (or dbPort option), while adding automatic fallback discovery to an available port (54335460) when 5432 is occupied on the host.

Context & Problem

Previously, the mail database sidecar hardcoded host port 5432 (export const MAIL_DB_PORT = 5432). On servers where an existing PostgreSQL instance or other service is already bound to port 5432, starting the mail stack immediately fails due to a port collision (Bind for 127.0.0.1:5432 failed: port is already allocated), blocking mail installation.

Key Changes

  1. Configurable Port & Validation (packages/adapters/src/infra/mail-container.ts):

    • Defined MAIL_DB_DEFAULT_PORT = 5432, MAIL_DB_FALLBACK_PORT = 5433, MAIL_DB_PORT_RANGE_MAX = 5460, and MAIL_DB_INTERNAL_PORT = 5432.
    • Added resolveMailDbPort(raw?: string | number) helper that checks process.env.OPENSHIP_MAIL_DB_PORT, validates integer boundaries (1..65535), and falls back to 5432.
    • Maintained MAIL_DB_PORT = resolveMailDbPort() for backwards compatibility.
  2. Collision-Free Auto-Discovery (findAvailableMailDbPort in ensure-container-mail.ts):

    • When the user does not specify an explicit port and port 5432 is occupied on the host, OpenShip automatically scans 5433..5460 and selects the first available loopback port, logging the selection without failing.
    • If the user explicitly provided a port (opts.dbPort or OPENSHIP_MAIL_DB_PORT), that exact port is preserved without auto-switching.
  3. Cluster Port Retention (retainedDbPort in ensure-container-mail.ts):

    • When an existing initialised cluster is detected on disk (PG_VERSION), its assigned port is retained from engine.env, guaranteeing that repairs, restarts, or image swaps never alter the port of a live database.
  4. Container Port Mapping & Verification (ensure-container-mail.ts):

    • buildDbRunCommand maps -p ${MAIL_DB_HOST_BIND}:${dbPort}:${MAIL_DB_INTERNAL_PORT} so the internal container port remains standard 5432 while the published host loopback port is customizable.
    • startContainerMail and startDb check waitForPortListening(executor, dbPort).
  5. Daemon SQL Config Reconciliation (apps/email/docker/entrypoint.sh):

    • Added step 3c to reconcile daemon database configs (/etc/postfix, /etc/dovecot, /etc/amavis, /opt/iredapd, /etc/fail2ban) to communicate with OPENSHIP_MAIL_DB_PORT when non-default.
  6. Public API Exports (packages/adapters/src/index.ts):

    • Exported resolveMailDbPort, buildDbRunCommand, retainedDbPort, findAvailableMailDbPort, and port constants.
  7. Tests:

    • Added unit test suite in packages/adapters/src/infra/mail-container.test.ts.
    • Added unit tests in packages/adapters/src/system/mail/ensure-container-mail.test.ts covering buildDbRunCommand, findAvailableMailDbPort auto-discovery, and retainedDbPort.

Verification

  • Tested fallback on invalid values (negative, zero, >65535, NaN, float).
  • Tested auto-discovery when 5432 is occupied (binds 5433).
  • Tested multi-port collision auto-discovery (5432 & 5433 occupied -> binds 5434).
  • Tested explicit override preservation.
  • Tested retained port on existing clusters.
  • Unit tests pass (5/5).

Closes #828

@lagmandu
lagmandu force-pushed the feat/configurable-mail-db-port branch 3 times, most recently from 11a2711 to 0bb884a Compare September 4, 2026 16:49
…fallback

Make the PostgreSQL sidecar host port configurable via OPENSHIP_MAIL_DB_PORT
to resolve port conflicts when port 5432 is already occupied by a host service.
Adds automatic free-port discovery (5433..5460) when the default port is
occupied, retains previously assigned ports for existing clusters, and
reconciles daemon SQL connection configs on non-default ports.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Improvement]: Make mail server sql port configurable

1 participant