diff --git a/app/docs/[section]/[[...slug]]/page.tsx b/app/docs/[section]/[[...slug]]/page.tsx index 363c487..1e91f6d 100644 --- a/app/docs/[section]/[[...slug]]/page.tsx +++ b/app/docs/[section]/[[...slug]]/page.tsx @@ -133,12 +133,14 @@ export default async function ArticlePage({ params }: PageProps) { const navigationLinks = navigation.map((item) => { // Better matching logic for active state // For index files, match both /section and /section/index - // For other files, match the specific file name + // For other files, match the specific file name. Compare the final path + // segment exactly - a substring test marks every sibling whose slug + // starts with this one (packages also matching packages-operations). const itemPath = item.link.replace('/docs/', ''); const currentPath = file === 'index' ? section : `${section}/${file}`; const isActive = itemPath === currentPath || (file === 'index' && itemPath === `${section}/index`) || - (item.link.includes(file) && file !== 'index'); + (file !== 'index' && item.link.split('/').pop() === file); return ( /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}`; } @@ -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]' \\ diff --git a/app/services/articleService.ts b/app/services/articleService.ts index 3f37b21..480ec8c 100644 --- a/app/services/articleService.ts +++ b/app/services/articleService.ts @@ -8,6 +8,20 @@ import { buildAptInstallCommand, buildRpmInstallCommand } from '../lib/packageIn import { documentdbDiscordUrl } from './externalLinks'; const articlesDirectory = path.join(process.cwd(), 'articles'); + +// Sections served entirely from this file rather than from the cloned +// articles/ tree. Getting Started holds quick starts only; the longer-form +// deployment guides live in their own section, alongside DocumentDB Local. +const virtualSections: Record = { + 'linux-packages': { + landingTitle: 'Linux Packages', + pages: [ + { slug: '', title: 'Operating a Package Install' }, + { slug: 'offline', title: 'Offline / Air-gapped Install' }, + ], + }, +}; + const dockerGuideContent = `# Docker Quick Start Run DocumentDB locally with Docker and verify the setup before moving to driver code. @@ -145,100 +159,106 @@ If something does not work as expected: const linuxPackagesGuideContent = `# Linux Packages Quick Start -Install DocumentDB on Debian, Ubuntu, or RHEL-compatible hosts from the published package repository. +Install DocumentDB from the published package repository and get a MongoDB-compatible endpoint on your own host. -## Install +**Ubuntu 24.04 and RHEL-compatible 9, on PostgreSQL 17 or 18**, get the full stack — extension, gateway, setup wizard and systemd units. Every other target gets the PostgreSQL extension without the endpoint: use the [Docker Quick Start](/docs/getting-started/docker) for an endpoint in one command, or the [Package Finder](/packages) for any other distribution, architecture or PostgreSQL major. -**Ubuntu 24.04 and RHEL-compatible 9, on PostgreSQL 17 or 18**, get the full stack — extension, gateway, setup wizard and systemd units. Every other target is extension-only: see [Other targets](#other-targets). +You do not need PostgreSQL already installed — the setup wizard creates and manages its own instance. The install does add the PGDG repository and pull PostgreSQL, PostGIS and around 160 packages (about 140 MB), so pick a host you are willing to have PGDG on. + +## Install ### 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). +For PostgreSQL 17, install \`documentdb-17\`; there is no \`documentdb-16\`. Keep the \`crb\` line on RHEL — without it \`dnf\` fails on \`libqhull_r.so.7\`. -> [!NOTE] -> In a container running as \`root\`, drop the leading \`sudo\` (it is often not installed). Leave \`sudo -u \` commands alone — those switch user rather than elevate; run them as \`su -c '...'\` instead. On Debian/Ubuntu also \`export DEBIAN_FRONTEND=noninteractive\` first, or \`tzdata\` prompts and the install hangs with no visible error. +Then install \`mongosh\`, which you need to talk to the endpoint: -> [!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. +\`\`\`bash +# Ubuntu 24.04 +curl -fsSL https://pgp.mongodb.com/server-8.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb.gpg +echo "deb [signed-by=/usr/share/keyrings/mongodb.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb.list +sudo apt update && sudo apt install -y mongodb-mongosh -> [!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. +# RHEL-compatible 9 +printf '[mongodb-org-8.0]\\nname=MongoDB\\nbaseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/$basearch/\\ngpgcheck=1\\nenabled=1\\ngpgkey=https://pgp.mongodb.com/server-8.0.asc\\n' | sudo tee /etc/yum.repos.d/mongodb.repo +sudo dnf install -y mongodb-mongosh +\`\`\` ## Set up and connect +> [!IMPORTANT] +> The wizard binds the gateway on **all interfaces** (\`0.0.0.0:10260\`) with a self-signed certificate. Firewall port \`10260\` before you run it on anything but a private machine, then read [Before exposing it to a network](/docs/linux-packages#before-exposing-it-to-a-network). + Installing the packages puts files on disk; it does not create a database or start the endpoint. The setup wizard does that: \`\`\`bash sudo documentdb-setup --admin-user admin \`\`\` -It creates the PostgreSQL instance, installs the extensions, bootstraps the admin user, starts the gateway, and enables \`documentdb-local@.target\` so the stack survives reboot. It **prompts for the admin password**; for servers and CI pass \`--admin-password-file \` or \`--admin-password-stdin\` together with \`--yes\`. +It creates the PostgreSQL instance, installs the extensions, starts the gateway, and enables it at boot. It **prompts for the admin password**. -\`mongosh\` is not shipped by these packages. Install it from MongoDB's own repository — these are the two paved-road targets, and the [official instructions](https://www.mongodb.com/docs/mongodb-shell/install/) cover every other platform: +Now open a shell against the endpoint: \`\`\`bash -# Ubuntu 24.04 -curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-8.0.gpg -echo "deb [signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg] https://repo.mongodb.org/apt/ubuntu noble/mongodb-org/8.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list >/dev/null -sudo apt update && sudo apt install -y mongodb-mongosh - -# RHEL-compatible 9 -printf '%s\\n' '[mongodb-org-8.0]' 'name=MongoDB Repository' \\ - "baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/$(uname -m)/" \\ - 'gpgcheck=1' 'enabled=1' 'gpgkey=https://pgp.mongodb.com/server-8.0.asc' | sudo tee /etc/yum.repos.d/mongodb-org-8.0.repo >/dev/null -sudo dnf install -y mongodb-mongosh +mongosh localhost:10260 -u admin -p '' --authenticationMechanism SCRAM-SHA-256 \\ + --tls --tlsAllowInvalidCertificates \`\`\` -Then connect. A bare \`-p\` makes \`mongosh\` **prompt** for the password, so pass it inline in scripts and CI — otherwise a non-interactive shell sends an empty password and fails with the unhelpful \`MongoServerError: Invalid key\`: +A database and collection are created on first write: -\`\`\`bash -mongosh localhost:10260 -u admin -p '' --authenticationMechanism SCRAM-SHA-256 \\ - --tls --tlsAllowInvalidCertificates --eval 'db.runCommand({ping: 1})' +\`\`\`javascript +> db.orders.insertOne({ item: "widget", qty: 5 }) +{ acknowledged: true, insertedId: ObjectId('...') } + +> db.orders.find() +[ { _id: ObjectId('...'), item: 'widget', qty: 5 } ] \`\`\` -Or as a URI — percent-encode reserved characters in the password (\`@\` becomes \`%40\`), or it misparses: +**That is a working DocumentDB.** Confirm the service state with \`sudo documentdb-setup --status\` and the version with \`documentdb-gateway --version\`. -\`\`\`bash -mongosh 'mongodb://admin:@127.0.0.1:10260/mydb?tls=true&tlsAllowInvalidCertificates=true' \\ - --eval 'db.runCommand({ping: 1})' -\`\`\` +## Where to go next -A database and collection are created on first write: +- Build an application: [Node.js Quick Start](/docs/getting-started/nodejs-setup) or [Python Quick Start](/docs/getting-started/python-setup) +- Secure it, manage services, run SQL, upgrade, uninstall, and hosts without systemd: [Operating a package install](/docs/linux-packages) +- Install without internet access: [Offline / air-gapped install](/docs/linux-packages/offline) +- Another distribution, architecture or PostgreSQL major: [Package Finder](/packages) -\`\`\`javascript -db.orders.insertOne({ item: "widget", qty: 5 }) -db.orders.find() -\`\`\` +## Troubleshooting + +- \`Unable to locate package documentdb-18\` (apt) / \`No match for argument: documentdb-18\` (dnf) — the DocumentDB repository was not added, or that target is extension-only. Check the [Package Finder](/packages) +- \`documentdb-18 : Depends: postgresql-18 but it is not installable\` — PGDG was not added first +- \`nothing provides libqhull_r.so.7\` — the \`crb\` line did not run +- \`MongoServerError: Invalid key\` — empty or wrong password; a bare \`-p\` prompts, so a non-interactive shell sends nothing +- Anything else — \`sudo documentdb-setup --status\` reports the listener, service states and resolved paths + +More failure modes, including other distributions and hosts without systemd: [Operating a package install](/docs/linux-packages#troubleshooting). +`; + +const linuxPackagesOperationsContent = `# Operating a package install + +Day-2 operations for a DocumentDB installed from Linux packages: securing the endpoint, managing services, running SQL, upgrading, and removal. Install first with the [Linux Packages Quick Start](/docs/getting-started/packages). ## Before exposing it to a network -The gateway binds **all interfaces** (\`0.0.0.0:10260\` and \`[::]:10260\`) by default, even though the connect string above says \`127.0.0.1\`. The PostgreSQL instance behind it stays on loopback. +The gateway binds **all interfaces** (\`0.0.0.0:10260\` and \`[::]:10260\`) by default. The PostgreSQL instance behind it stays on loopback. Before using this anywhere but a private machine: -- Restrict the listener with \`DOCUMENTDB_LISTEN_ADDR=127.0.0.1:10260\` in \`/etc/documentdb/local//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//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//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\`. -## Verify and operate +## Services and paths \`\`\`bash sudo documentdb-setup --status # gateway listener, service states, resolved paths @@ -246,17 +266,17 @@ documentdb-gateway --version # DocumentDB version dpkg -l | grep documentdb # or: rpm -qa | grep documentdb \`\`\` -> Do not use \`db.version()\` or \`buildInfo\` in \`mongosh\` to check the DocumentDB version — those report the emulated MongoDB wire version, not DocumentDB's. - | Thing | Where | | --- | --- | | Gateway port | \`10260\` | | PostgreSQL port | \`9700 + \` (9718 for PG 18), loopback only | -| Gateway log | \`/var/lib/documentdb-gateway/gateway.log\` | -| PostgreSQL log | \`/var/lib/documentdb-local//data/pglog.log\` | +| Gateway log | systemd: \`journalctl -u documentdb-gateway-local@18.service\` · otherwise \`/var/lib/documentdb-gateway/gateway.log\` | +| PostgreSQL log | systemd: \`journalctl -u documentdb-postgresql@18.service\` · otherwise \`/var/lib/documentdb-local//data/pglog.log\` | | Setup state / gateway env | \`/etc/documentdb/local//setup.conf\`, \`.../gateway.env\` | -Day 2 (units are templated per PostgreSQL major): +On a systemd host both services log to the journal; the log **files** above exist only when \`documentdb-setup\` falls back to its non-systemd \`nohup\` mode. \`documentdb-setup --status\` prints whichever applies to your host. + +Units are templated per PostgreSQL major: \`\`\`bash sudo systemctl status documentdb-local@18.target @@ -264,12 +284,7 @@ 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. - -> [!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\`. - -### Running SQL against the managed instance +## Running SQL against the managed instance \`documentdb-setup\` runs a private instance as the \`documentdb-local\` user on a socket, so a bare \`psql\` will not find it: @@ -277,20 +292,30 @@ sudo systemctl stop documentdb-local@18.target sudo -u documentdb-local psql -h /run/documentdb-local/18/postgresql -p 9718 -d postgres \`\`\` -Use that connection for the \`ALTER EXTENSION\` statements under [Upgrading](#upgrading), and to read the installed versions: - \`\`\`sql SELECT extname, extversion FROM pg_extension WHERE extname LIKE 'documentdb%'; \`\`\` -### Remove or reset +## Upgrading + +A package upgrade only replaces files. Afterwards, update the extensions in every database that has DocumentDB installed: + +\`\`\`sql +ALTER EXTENSION documentdb_core UPDATE; +ALTER EXTENSION documentdb UPDATE; +ALTER EXTENSION documentdb_extended_rum UPDATE; -- only if installed +\`\`\` + +PostgreSQL applies intermediate upgrade scripts automatically. In-place upgrades are not yet a fully tested path, so take a backup first. + +## Remove or reset \`\`\`bash -# Stop the stack first — package removal deletes files but does not stop a -# running gateway. On systemd hosts: +# Stop the stack first. On systemd hosts: sudo systemctl stop documentdb-local@18.target +# Without systemd, use an UNSCOPED restore (no --pg-version): +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 # Name the package you installed AND the extension: autoremove does not reap @@ -299,54 +324,67 @@ sudo apt purge --autoremove documentdb-18 postgresql-18-documentdb sudo dnf remove documentdb-18 postgresql18-documentdb && sudo dnf autoremove \`\`\` -## Upgrading +Confirm the stack is down first with \`ss -lnt | grep 10260\`. A gateway still running when its packages go keeps serving from a deleted binary. 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. -A package upgrade only replaces files. Afterwards, update the extensions in every database that has DocumentDB installed: - -\`\`\`sql -ALTER EXTENSION documentdb_core UPDATE; -ALTER EXTENSION documentdb UPDATE; -ALTER EXTENSION documentdb_extended_rum UPDATE; -- only if installed -\`\`\` +## Known issues in 0.116 -PostgreSQL applies intermediate upgrade scripts automatically. In-place upgrades are not yet a fully tested path, so take a backup first. +These are defects in this release, not expected behaviour. Most need a host without systemd to hit; the two marked **any host** do not. -## Other targets +| Area | Issue | Affects | +| --- | --- | --- | +| Status | \`documentdb-setup --status\` can report "active" for any process holding port 10260 | **any host** | +| Upgrade | \`documentdb-setup\` does not run \`ALTER EXTENSION documentdb_core UPDATE\`; run it yourself | **any host** | +| Restart | Re-running \`documentdb-setup\` to restart can hang; redirecting output to a file avoids it | no systemd | +| Stop | \`documentdb-setup --restore --pg-version N\` reports success without stopping the gateway — use an unscoped \`--restore\`, which stops every major on the host | no systemd | +| Minimal RHEL | Install \`procps-ng\` first, or \`--restore\` reports success while the gateway keeps serving and a later run fails with \`Port 10260 is already in use\` | no systemd | +| Reset | \`documentdb-local-reset --confirm-destroy\` can report success while leaving a PostgreSQL process running | no systemd | -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). +**Prefer a systemd host for anything you care about**, where the service lifecycle is managed by systemd rather than by the setup script. -| Distribution | PGDG suite | Repository component | Install | -| --- | --- | --- | --- | -| Ubuntu 24.04 | \`noble-pgdg\` | \`ubuntu24\` | \`documentdb-18\` / \`documentdb-17\` — full stack | -| RHEL-compatible 9 | — | \`rpm/rhel9\` | \`documentdb-18\` / \`documentdb-17\` — full stack | -| Ubuntu 22.04 | \`jammy-pgdg\` | \`ubuntu22\` | \`postgresql-18-documentdb\` | -| Debian 11 | \`bullseye-pgdg\` | \`deb11\` | \`postgresql-17-documentdb\` — **PG 18 not installable** | -| Debian 12 | \`bookworm-pgdg\` | \`deb12\` | \`postgresql-18-documentdb\` | -| Debian 13 | \`trixie-pgdg\` | \`deb13\` | \`postgresql-18-documentdb\` | -| RHEL-compatible 8 | — | \`rpm/rhel8\` | \`postgresql18-documentdb\` — \`EL-8\` URLs, \`powertools\` not \`crb\` | +## Multiple PostgreSQL majors -The APT repository is \`https://documentdb.io/deb stable \`; the RPM baseurl is \`https://documentdb.io/rpm/\`. It serves **0.116** on the full-stack targets and **0.114** everywhere else — \`apt-cache madison \` / \`dnf --showduplicates list \` show the truth. +Install the matching \`documentdb-N\` for every major you configure. \`documentdb-setup\` refuses a major whose extension package is missing: -**Debian 11 has no PostgreSQL 18** — the upstream Bullseye PostGIS build does not exist, so the install fails with \`Depends: postgresql-18-postgis-3 but it is not installable\`. Use 16 or 17. - -**Debian 13:** \`apt.postgresql.org\` also publishes this extension and its version sorts higher, so PGDG's build installs by default. Pin with \`apt install postgresql-18-documentdb=\` for this repository's copy. +\`\`\`text +ERROR: The DocumentDB extension package is not installed for PostgreSQL 17 +(/usr/share/postgresql/17/extension/documentdb.control is missing). +\`\`\` -Confirm the extension landed: +Each major also needs its own gateway port — the second one fails on \`Gateway port 10260 is already in use\` unless you pass \`--gateway-port\`: \`\`\`bash -apt-cache policy postgresql-18-documentdb # or: dnf info postgresql18-documentdb -dpkg -L postgresql-18-documentdb | grep -E 'documentdb.*\\.(control|sql|so)$' | head +sudo documentdb-setup --pg-version 17 --gateway-port 10261 --admin-user admin \`\`\` -For a MongoDB-compatible endpoint on these hosts, use the [Docker Quick Start](/docs/getting-started/docker), or run the gateway from source against your host PostgreSQL with \`scripts/start_oss_server.sh\` and \`scripts/build_and_start_gateway.sh\` in the [DocumentDB repository](https://github.com/documentdb/documentdb). Run those as an unprivileged user, and \`export TERM=xterm\` first in non-interactive shells or the script aborts on \`tput\`. +## Troubleshooting + +Failure modes beyond the four in the [quick start](/docs/getting-started/packages#troubleshooting): + +- \`Bad GPG signature\` on \`pgdg-common\` — wrong architecture in the PGDG repository URL +- \`apt install\` hangs in a container — \`export DEBIAN_FRONTEND=noninteractive\` first, and drop the leading \`sudo\` when running as \`root\` (minimal images often have no \`sudo\`). Keep \`sudo -u \`, which switches user; \`su documentdb-local -c\` fails because that account has \`/usr/sbin/nologin\`, so use \`su -s /bin/bash documentdb-local -c '...'\` +- Debian 11 has PostgreSQL 18 from PGDG but no \`postgresql-18-postgis-3\` for Bullseye, so the dependency set cannot be satisfied; use 16 or 17 +- \`ss: command not found\` on a minimal RHEL host — install \`iproute\`; the DocumentDB packages do not pull it in +- Debian 13 also gets this extension from \`apt.postgresql.org\`, whose version sorts higher; pin with \`apt install postgresql-18-documentdb=\` for this repository's build +- \`db.version()\` and \`buildInfo\` in \`mongosh\` report the emulated MongoDB wire version, not DocumentDB's — use \`documentdb-gateway --version\` + +## Multiple PostgreSQL majors + +Install the matching \`documentdb-N\` for every major you configure. \`documentdb-setup --pg-version N\` will happily configure a major whose package is absent, and nothing then owns the result — a later \`autoremove\` can reap \`documentdb-common\` out from under it. -## Offline / air-gapped install +## Unattended setup + +\`documentdb-setup\` prompts for the admin password. For servers and CI, pass \`--admin-password-file \` or \`--admin-password-stdin\` together with \`--yes\`. +`; + +const linuxPackagesOfflineContent = `# Offline / air-gapped install An air-gapped host has no route to PGDG either, and DocumentDB pulls PostgreSQL, \`pg_cron\`, \`pgvector\` and PostGIS from there — the release assets alone are not enough. Stage the full dependency closure on a connected machine with the **same distribution, release and architecture** as the target. -### Stage the bundle (connected machine) +For a connected host, use the [Linux Packages Quick Start](/docs/getting-started/packages) instead. + +## Stage the bundle (connected machine) -With the same repositories configured as for an online install — run the [Install](#install) command for your distribution **up to and including \`apt update\` / the \`dnf config-manager\` line, but not the final \`install\`**: +Configure the repositories exactly as for an online install: run the whole [Install](/docs/getting-started/packages#install) block for your distribution **except the final \`sudo apt install -y documentdb-18\` / \`sudo dnf install -y documentdb-18\` line** — delete that line and the \`&& \\\` that precedes it. On RHEL the DocumentDB repository is written by the \`tee /etc/yum.repos.d/documentdb.repo\` line near the end, so stopping earlier leaves \`dnf download\` with nothing to find. Then: \`\`\`bash # Debian / Ubuntu @@ -370,9 +408,9 @@ createrepo_c bundle > [!NOTE] > **Use the full-closure flags, not \`--download-only\`.** \`apt-get install --download-only\` and a bare \`dnf download --resolve\` skip whatever is already installed on the staging machine; the bundle looks complete and the target dies with \`Depends: adduser but it is not installable\`. -Expect ~200 packages / 200 MB (DEB) or ~270 / 170 MB (RPM), mostly PostGIS and GDAL. The \`unsandboxed as root\` and \`dpkg-scanpackages ... override file\` warnings are harmless. +Expect ~200 packages / 200 MB (DEB) or ~270 / 170 MB (RPM), mostly PostGIS and GDAL. That is more than an online install downloads, because the closure includes packages already present on the staging machine. The \`unsandboxed as root\` and \`dpkg-scanpackages ... override file\` warnings are harmless. -### Install from the bundle (air-gapped target) +## Install from the bundle (air-gapped target) Copy \`bundle/\` across — including the \`Packages\`/\`Packages.gz\` or \`repodata/\` index inside it, which is what makes the next step resolve — and point the package manager at it: @@ -397,35 +435,16 @@ sudo dnf install -y --disablerepo='*' --enablerepo=documentdb-offline documentdb \`[trusted=yes]\` / \`gpgcheck=0\` accept the unsigned local directory. Upstream signatures were verified at staging time; \`sha256sum\` the transfer if it crosses an untrusted boundary. -Then continue with **Set up and connect** above — \`documentdb-setup\` needs no network. +Then continue with [Set up and connect](/docs/getting-started/packages#set-up-and-connect) — \`documentdb-setup\` needs no network. -### Smaller offline cases +\`mongosh\` is **not** part of the bundle and the target cannot reach the MongoDB repository, so stage it in the same pass if you want to verify from the air-gapped host — add \`mongodb-mongosh\` to the package list after configuring the MongoDB repository shown in the quick start. Otherwise verify with \`sudo documentdb-setup --status\` and connect from a machine that does have \`mongosh\`. + +## Smaller offline cases If the target already has PostgreSQL, the PGDG extension dependencies (\`postgresql-N-cron\`, \`-pgvector\`, \`-postgis-3\`) and \`jq\`, you do not need a bundle: - **Extension only, one file** — \`sudo apt install ./ubuntu24.04-postgresql-18-documentdb_0.116-0_amd64.deb\`. No gateway and no \`documentdb-setup\`. - **Full stack from the release assets** — pass all six files for your platform to a *single* \`apt install\` / \`dnf install\`. Local files resolve dependencies only against enabled repositories, so the meta package on its own fails with \`Depends: documentdb-18 ... but it is not installable\`. - -## Troubleshooting - -- \`sudo documentdb-setup --status\` reports the listener, service states and resolved paths -- \`has no installation candidate\` / \`No match for argument\` — that target is extension-only, or PGDG was not added first. See [Other targets](#other-targets) -- \`nothing provides libqhull_r.so.7\` — the \`crb\` line did not run -- \`Depends: postgresql-N-documentdb but it is not installable\` — wrong \`arch=\` for the host -- \`Bad GPG signature\` on \`pgdg-common\` — wrong architecture in the PGDG reporpm URL -- \`apt install\` hangs in a container — \`export DEBIAN_FRONTEND=noninteractive\` -- Debian 11 has no PostgreSQL 18 (no upstream Bullseye PostGIS); use 16 or 17 - -## Next steps - -- [Docker Quick Start](/docs/getting-started/docker) -- [Building the packages from source](https://github.com/documentdb/documentdb/blob/main/packaging/README.md) -- [Mongo Shell Quick Start](/docs/getting-started/mongo-shell-quickstart) -- [Node.js Quick Start](/docs/getting-started/nodejs-setup) -- [Python Quick Start](/docs/getting-started/python-setup) -- [API Reference](/docs/reference) -- [Samples Gallery](/samples) -- [Package Finder](/packages) `; const vscodeQuickStartGuideContent = `# Visual Studio Code Quick Start @@ -1206,10 +1225,32 @@ function updateDocumentDbLocalContent(content: string): string { export function getArticleContent(): Article { const contentPath = path.join(articlesDirectory, 'content.yml'); const fileContents = fs.readFileSync(contentPath, 'utf8'); - return loadYaml(fileContents) as Article; + const article = loadYaml(fileContents) as Article; + + // content.yml is cloned from the docs repo and does not know about sections + // served from this file, so surface them on the landing page here. + if (!article.landing.links.some((link) => link.link === '/docs/linux-packages')) { + const localIndex = article.landing.links.findIndex((link) => link.link === '/docs/documentdb-local'); + const linuxPackagesLink = { title: 'Linux Packages', link: '/docs/linux-packages' }; + article.landing.links.splice( + localIndex >= 0 ? localIndex + 1 : article.landing.links.length, + 0, + linuxPackagesLink, + ); + } + + return article; } export function getArticleNavigation(section: string): Link[] { + const virtual = virtualSections[section]; + if (virtual) { + return virtual.pages.map(page => ({ + title: page.title, + link: page.slug ? `/docs/${section}/${page.slug}` : `/docs/${section}`, + })); + } + const navPath = path.join(articlesDirectory, section, 'navigation.yml'); if (!fs.existsSync(navPath)) { @@ -1279,7 +1320,7 @@ export function getAllSections(): string[] { .filter(dirent => dirent.isDirectory()) .map(dirent => dirent.name); - return sections; + return [...sections, ...Object.keys(virtualSections)]; } export function getAllArticlePaths(): { section: string; slug: string[] }[] { @@ -1287,6 +1328,14 @@ export function getAllArticlePaths(): { section: string; slug: string[] }[] { const paths: { section: string; slug: string[] }[] = []; sections.forEach(section => { + const virtual = virtualSections[section]; + if (virtual) { + virtual.pages.forEach(page => { + paths.push({ section, slug: page.slug ? [page.slug] : [] }); + }); + return; + } + const sectionPath = path.join(articlesDirectory, section); const files = fs.readdirSync(sectionPath, { withFileTypes: true }) .filter(dirent => dirent.isFile() && dirent.name.endsWith('.md')) @@ -1329,6 +1378,32 @@ export function getArticleByPath(section: string, slug: string[] = []): { const file = slug.length > 0 ? slug[slug.length - 1] : 'index'; const navigation = getArticleNavigation(section); + if (section === 'linux-packages' && file === 'index') { + return { + content: linuxPackagesOperationsContent, + frontmatter: { + title: 'Operating a Package Install', + description: 'Secure, manage, upgrade and remove a DocumentDB installed from Linux packages, plus known issues in 0.116.', + }, + navigation, + section, + file, + }; + } + + if (section === 'linux-packages' && file === 'offline') { + return { + content: linuxPackagesOfflineContent, + frontmatter: { + title: 'Offline / Air-gapped Install', + description: 'Stage a full dependency closure on a connected machine and install DocumentDB on a host with no internet access.', + }, + navigation, + section, + file, + }; + } + if (section === 'getting-started' && file === 'docker') { return { content: dockerGuideContent, diff --git a/tests/packageInstall.test.ts b/tests/packageInstall.test.ts index c1c0ba8..15f309b 100644 --- a/tests/packageInstall.test.ts +++ b/tests/packageInstall.test.ts @@ -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}`); @@ -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}`);