Skip to content
Merged
18 changes: 13 additions & 5 deletions app/lib/packageInstall.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type AptDistro = "ubuntu22" | "ubuntu24" | "deb11" | "deb12" | "deb13";
export type RpmDistro = "rhel8" | "rhel9";
export type AptArch = "amd64" | "arm64";
export type RpmArch = "x86_64" | "aarch64";
export type AptArch = "amd64" | "arm64" | "auto";
export type RpmArch = "x86_64" | "aarch64" | "auto";
export type AptPgVersion = "16" | "17" | "18";
export type RpmPgVersion = "16" | "17" | "18";

Expand Down Expand Up @@ -78,6 +78,11 @@ export function buildAptInstallCommand(
aptPgVersion: AptPgVersion,
): string {
const pgdgSuite = aptPgdgSuites[aptTarget];
// "auto" resolves the architecture on the host running the command, so a
// single published example is copy-pasteable on both amd64 and arm64. The
// Package Finder passes a literal architecture, because there the user has
// chosen one explicitly.
const arch = aptArch === "auto" ? "$(dpkg --print-architecture)" : aptArch;
// `documentdb-N` pulls the whole stack (extension + gateway + tools +
// documentdb-common) and owns the systemd lifecycle for that major.
const installTarget = aptServesFullStack(aptTarget, aptPgVersion)
Expand All @@ -89,7 +94,7 @@ sudo apt install -y curl ca-certificates gnupg && \\
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor --yes -o /usr/share/keyrings/postgresql.gpg && \\
echo "deb [signed-by=/usr/share/keyrings/postgresql.gpg] https://apt.postgresql.org/pub/repos/apt ${pgdgSuite}-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list >/dev/null && \\
curl -fsSL https://documentdb.io/documentdb-archive-keyring.gpg | sudo gpg --dearmor --yes -o /usr/share/keyrings/documentdb-archive-keyring.gpg && \\
echo "deb [arch=${aptArch} signed-by=/usr/share/keyrings/documentdb-archive-keyring.gpg] https://documentdb.io/deb stable ${aptTarget}" | sudo tee /etc/apt/sources.list.d/documentdb.list >/dev/null && \\
echo "deb [arch=${arch} signed-by=/usr/share/keyrings/documentdb-archive-keyring.gpg] https://documentdb.io/deb stable ${aptTarget}" | sudo tee /etc/apt/sources.list.d/documentdb.list >/dev/null && \\
sudo apt update && \\
sudo apt install -y ${installTarget}`;
}
Expand All @@ -100,17 +105,20 @@ export function buildRpmInstallCommand(
rpmPgVersion: RpmPgVersion,
): string {
const rhelMajorVersion = rpmMajorVersions[rpmTarget];
// See buildAptInstallCommand: "auto" resolves on the host so one published
// example works on x86_64 and aarch64 alike.
const arch = rpmArch === "auto" ? "$(uname -m)" : rpmArch;
const installTarget = rpmServesFullStack(rpmTarget, rpmPgVersion)
? `documentdb-${rpmPgVersion}`
: `postgresql${rpmPgVersion}-documentdb`;

return `sudo dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${rhelMajorVersion}.noarch.rpm && \\
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-${rhelMajorVersion}-${rpmArch}/pgdg-redhat-repo-latest.noarch.rpm && \\
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-${rhelMajorVersion}-${arch}/pgdg-redhat-repo-latest.noarch.rpm && \\
sudo dnf -qy module disable postgresql && \\
sudo dnf install -y dnf-plugins-core && \\
(sudo dnf config-manager --set-enabled crb || \\
sudo dnf config-manager --set-enabled powertools || \\
sudo dnf config-manager --set-enabled codeready-builder-for-rhel-${rhelMajorVersion}-${rpmArch}-rpms) && \\
sudo dnf config-manager --set-enabled codeready-builder-for-rhel-${rhelMajorVersion}-${arch}-rpms) && \\
sudo rpm --import https://documentdb.io/documentdb-archive-keyring.gpg && \\
printf '%s\\n' \\
'[documentdb]' \\
Expand Down
34 changes: 17 additions & 17 deletions app/services/articleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,30 +154,19 @@ Install DocumentDB on Debian, Ubuntu, or RHEL-compatible hosts from the publishe
### Ubuntu 24.04, PostgreSQL 18 (APT)

\`\`\`bash
${buildAptInstallCommand('ubuntu24', 'amd64', '18')}
${buildAptInstallCommand('ubuntu24', 'auto', '18')}
\`\`\`

### RHEL-compatible 9, PostgreSQL 18 (RPM)

\`\`\`bash
${buildRpmInstallCommand('rhel9', 'x86_64', '18')}
${buildRpmInstallCommand('rhel9', 'auto', '18')}
\`\`\`

For PostgreSQL 17, install \`documentdb-17\`; the \`documentdb\` meta package is equivalent to \`documentdb-18\`. For any other distribution, architecture or major, use the [Package Finder](/packages).

> [!NOTE]
> In a container running as \`root\`, drop the leading \`sudo\` (it is often not installed). Leave \`sudo -u <user>\` commands alone — those switch user rather than elevate; run them as \`su <user> -c '...'\` instead. On Debian/Ubuntu also \`export DEBIAN_FRONTEND=noninteractive\` first, or \`tzdata\` prompts and the install hangs with no visible error.

> [!WARNING]
> **On ARM, change three strings** — the commands above are written for x86_64.
>
> | In | Replace | With |
> | --- | --- | --- |
> | APT \`documentdb.list\` line | \`arch=amd64\` | \`arch=$(dpkg --print-architecture)\` |
> | RPM PGDG URL | \`EL-9-x86_64\` | \`EL-9-$(uname -m)\` (same for \`EL-8-x86_64\`) |
> | RPM \`config-manager\` fallback | \`codeready-builder-for-rhel-9-x86_64-rpms\` | \`...-aarch64-rpms\` |
>
> Neither failure names the architecture. APT reports \`documentdb-18 : Depends: postgresql-18-documentdb but it is not installable\` — only the extension package is arch-specific, so it is the one that goes missing. DNF reports \`Bad GPG signature\` on \`pgdg-common\`, because PGDG ships a separate reporpm per architecture under an identical file name.
> In a container running as \`root\`, drop the leading \`sudo\` (it is often not installed). Leave \`sudo -u <user>\` commands alone — those switch user rather than elevate; run them as \`su -s /bin/bash <user> -c '...'\` instead. The \`-s\` is required because \`documentdb-local\` has \`/usr/sbin/nologin\` as its shell, so a bare \`su <user> -c\` fails with \`This account is currently not available.\` On Debian/Ubuntu also \`export DEBIAN_FRONTEND=noninteractive\` first, or \`tzdata\` prompts and the install hangs with no visible error.

> [!IMPORTANT]
> **Do not drop the \`crb\` line.** PostGIS pulls in \`gdal*-libs\`, which needs \`libqhull_r.so.7\`, and that ships only in CRB (\`powertools\` on EL8). Without it \`dnf install\` fails with \`nothing provides libqhull_r.so.7()(64bit)\`, naming GDAL but never the missing repository.
Expand Down Expand Up @@ -234,7 +223,7 @@ The gateway binds **all interfaces** (\`0.0.0.0:10260\` and \`[::]:10260\`) by d

Before using this anywhere but a private machine:

- Restrict the listener with \`DOCUMENTDB_LISTEN_ADDR=127.0.0.1:10260\` in \`/etc/documentdb/local/<major>/gateway.env\` and restart the service, or firewall port \`10260\`. Note that re-running \`documentdb-setup\` rewrites that file, so a firewall rule is the more durable control.
- Restrict the listener with \`DOCUMENTDB_LISTEN_ADDR=127.0.0.1:10260\` in \`/etc/documentdb/local/<major>/gateway.env\` and restart the service, or firewall port \`10260\`. **Re-running \`documentdb-setup\` silently resets this to a wildcard bind**, so re-check with \`grep DOCUMENTDB_LISTEN_ADDR /etc/documentdb/local/<major>/gateway.env\` afterwards. A firewall rule is the more durable control.
- Replace the auto-generated self-signed certificate. \`tlsAllowInvalidCertificates=true\` disables certificate validation — point \`DOCUMENTDB_TLS_CERT_FILE\` / \`DOCUMENTDB_TLS_KEY_FILE\` at a real certificate and drop that option.
- Use a strong admin password and create per-application users rather than sharing \`admin\`.

Expand Down Expand Up @@ -264,7 +253,10 @@ sudo systemctl restart documentdb-local@18.target
sudo systemctl stop documentdb-local@18.target
\`\`\`

**Without systemd** (containers, some dev images) the wizard starts the gateway directly and says so. \`systemctl\` will fail with *"System has not been booted with systemd"* — use \`documentdb-setup --status\` to inspect, re-run \`documentdb-setup\` to restart, \`--restore\` to stop.
**Without systemd** (containers, some dev images) the wizard starts the gateway directly and says so. \`systemctl\` will fail with *"System has not been booted with systemd"*.

> [!WARNING]
> **Prefer a systemd host.** Without it, several 0.116 lifecycle commands misreport: \`--status\` can show "active" for any process holding port 10260, re-running \`documentdb-setup\` to restart can hang, and \`--restore --pg-version N\` reports success without stopping the gateway — use an unscoped \`documentdb-setup --restore\`, which stops every major on the host.

> [!NOTE]
> On a **minimal RHEL-compatible image, install \`procps-ng\` first**. \`documentdb-setup\` locates the directly-started gateway with \`pgrep\`; without it \`--restore\` reports success while the gateway keeps serving, and a later re-run then fails with \`Port 10260 is already in use\`. Debian and Ubuntu images already ship \`procps\`.
Expand All @@ -289,6 +281,9 @@ SELECT extname, extversion FROM pg_extension WHERE extname LIKE 'documentdb%';
# Stop the stack first — package removal deletes files but does not stop a
# running gateway. On systemd hosts:
sudo systemctl stop documentdb-local@18.target
# Without systemd, use an UNSCOPED restore (no --pg-version); the scoped form
# reports success without stopping anything:
sudo documentdb-setup --restore

sudo documentdb-setup --restore # detach the managed integration
sudo documentdb-local-reset --pg-version 18 --confirm-destroy # DESTROYS the data directory
Expand All @@ -299,6 +294,9 @@ sudo apt purge --autoremove documentdb-18 postgresql-18-documentdb
sudo dnf remove documentdb-18 postgresql18-documentdb && sudo dnf autoremove
\`\`\`

> [!IMPORTANT]
> Confirm the stack is actually down first — \`ss -lnt | grep 10260\`. A gateway still running when its packages go keeps serving from a deleted binary with no shipped way to stop it. On a multi-major host remove one major at a time and re-check the survivor: \`documentdb-common\` owns the shared tooling and only \`documentdb-N\` holds it, so \`--autoremove\` can take it from a major still in use.

## Upgrading

A package upgrade only replaces files. Afterwards, update the extensions in every database that has DocumentDB installed:
Expand All @@ -313,7 +311,9 @@ PostgreSQL applies intermediate upgrade scripts automatically. In-place upgrades

## Other targets

The full stack is published only for **Ubuntu 24.04 and RHEL-compatible 9 on PostgreSQL 17 or 18**. Everywhere else — including **PostgreSQL 16 on every distribution** — you get the extension package alone: no gateway, no \`documentdb-setup\`, no systemd units. There is no \`documentdb-16\`; asking for it fails with *"has no installation candidate"* (APT) or *"No match for argument"* (DNF).
The full stack is published only for **Ubuntu 24.04 and RHEL-compatible 9 on PostgreSQL 17 or 18**. Everywhere else — including **PostgreSQL 16 on every distribution** — the repository serves only the extension package. There is no \`documentdb-16\`; asking for it fails with *"has no installation candidate"* (APT) or *"No match for argument"* (DNF).

Install the matching \`documentdb-N\` for every major you configure. \`documentdb-setup --pg-version N\` will happily configure a major whose package is absent — including PostgreSQL 16 — and nothing then owns the result, so a later \`apt autoremove\` can remove the tooling out from under it.

| Distribution | PGDG suite | Repository component | Install |
| --- | --- | --- | --- |
Expand Down
17 changes: 17 additions & 0 deletions tests/packageInstall.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ describe('buildAptInstallCommand', () => {
expect(command).toContain(`[arch=${arch} `);
});

it('resolves the architecture on the host when arch is "auto"', () => {
const command = buildAptInstallCommand('ubuntu24', 'auto', '18');
// The published doc example must be copy-pasteable on amd64 and arm64
// alike, so it shells out rather than baking in an architecture.
expect(command).toContain('[arch=$(dpkg --print-architecture) ');
expect(command).not.toContain('[arch=amd64 ');
expect(command).not.toContain('[arch=arm64 ');
});

it.each(aptDistros)('uses %s as the DocumentDB repository component', (distro) => {
const command = buildAptInstallCommand(distro, 'amd64', aptTargetPgVersions[distro][0]);
expect(command).toContain(`documentdb.io/deb stable ${distro}`);
Expand Down Expand Up @@ -130,6 +139,14 @@ describe('buildRpmInstallCommand', () => {
expect(command).toContain(`codeready-builder-for-rhel-9-${arch}-rpms`);
});

it('resolves the architecture on the host when arch is "auto"', () => {
const command = buildRpmInstallCommand('rhel9', 'auto', '18');
expect(command).toContain('EL-9-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm');
expect(command).toContain('codeready-builder-for-rhel-9-$(uname -m)-rpms');
expect(command).not.toContain('EL-9-x86_64');
expect(command).not.toContain('EL-9-aarch64');
});

it.each(rpmDistros)('points the DocumentDB repository at rpm/%s', (distro) => {
const command = buildRpmInstallCommand(distro, 'x86_64', '16');
expect(command).toContain(`baseurl=https://documentdb.io/rpm/${distro}`);
Expand Down