-
Package Finder
-
-
- Package format
- setPackageFamily(event.target.value as PackageFamily)}
- className={finderSelectClass}
- >
- APT (Ubuntu 24.04)
- RPM (EL9)
+
+ Linux distribution
+
+ choose(selectInstallTarget(selection, event.target.value))} className={selectClass}>
+ {Object.entries({ ...aptTargetLabels, ...rpmTargetLabels }).map(([value, label]) => (
+ {label}
+ ))}
+
+
+
+ Advanced options: PostgreSQL {pg}, {arch === "auto" ? "automatic architecture" : arch}
+
+
+
+ PostgreSQL major
+ changeChoice("pg", event.target.value)} className={selectClass}>
+ {aptTargetPgVersions.ubuntu24.map((value) => {value}{value === "18" ? " (recommended)" : ""} )}
+
+
+
+ Host architecture
+ changeChoice("arch", event.target.value)} className={selectClass}>
+ Detect on the Linux host (recommended)
+ {(family === "apt" ? ["amd64", "arm64"] : ["x86_64", "aarch64"]).map((value) => {value} )}
-
- {packageFamily === "apt" ? (
-
- Distribution
- setAptTarget(event.target.value as AptDistro)}
- className={finderSelectClass}
- >
- {Object.entries(aptTargetLabels).map(([value, label]) => (
-
- {label}
-
- ))}
-
-
- ) : (
-
- Distribution
- setRpmTarget(event.target.value as RpmDistro)}
- className={finderSelectClass}
- >
- {Object.entries(rpmTargetLabels).map(([value, label]) => (
-
- {label}
-
- ))}
-
-
- )}
-
- {packageFamily === "apt" ? (
-
- Architecture
- setAptArch(event.target.value as AptArch)}
- className={finderSelectClass}
- >
- amd64
- arm64
-
-
- ) : (
-
- Architecture
- setRpmArch(event.target.value as RpmArch)}
- className={finderSelectClass}
- >
- x86_64
- aarch64
-
-
- )}
-
- {packageFamily === "apt" ? (
-
- PostgreSQL version
- setAptPgVersion(event.target.value as AptPgVersion)}
- className={finderSelectClass}
- >
- {availableAptPgVersions.map((pgVersion) => (
-
- {pgVersion}
-
- ))}
-
-
- ) : (
-
- PostgreSQL version
- setRpmPgVersion(event.target.value as RpmPgVersion)}
- className={finderSelectClass}
- >
- 17
- 18
-
-
- )}
-
+
+
+ Architecture is resolved in your terminal, not from your browser. Use a supported AMD64 or ARM64 Linux host with sudo and systemd.
+ Registered RHEL needs an active subscription.
+
+
-
-
- Target: {selectedTargetText} · Architecture: {selectedArchText} · package names{" "}
- {selectedPackageNames}
+
+ Pre-GA: fresh installations only
+
+ Use a clean supported Linux host. In-place package upgrades from earlier releases are
+ not supported. Removing packages preserves database files; reinstalling is not a data reset.
-
- The generated command adds the PostgreSQL upstream repositories that provide
- PostgreSQL, pg_cron,{" "}
- pgvector, PostGIS, and{" "}
- rum for PostgreSQL 17.
+
+
+
+ {releaseStatus === "loading" ? (
+
Checking the published package release...
+ ) : releaseStatus === "fallback" ? (
+
+
Cannot confirm the current repository release. {releaseError}
+
+ Reference release: {release.tagName}, not confirmed current. Installation commands are
+ withheld until availability can be confirmed.{" "}
+ Browse release assets {" "}
+ or window.location.reload()} className={linkClass}>retry the lookup .
+
+
+ ) : (
+
+ Published repository release:{" "}
+ {release.tagName}
+ {" · "}{targetLabel}{" · "}{arch === "auto" ? "AMD64 / ARM64" : arch}
+
+ )}
+
+ {selectionReady && releaseStatus === "live" && !packagesAvailable && (
+
+ The complete package set for this selection is not present in the published release.
+ Choose another target or a specific available architecture, or{" "}
+ inspect the release assets .
-
- It installs the full DocumentDB stack for this target: the extension, the gateway
- runtime, the administrator tools and the systemd units.
+ )}
+
+
+ 1. Install the packages
+
+ Run this in your Linux terminal. It adds the PostgreSQL and DocumentDB repositories
+ and signing keys, enables the required distribution repositories, and installs the complete
+ stack. Review the command before running it. Installation does not start a usable DocumentDB endpoint.
- {isFullStack ? (
- <>
-
- Then run the setup wizard. The generated command pins the PostgreSQL major
- you selected and creates a new private instance, so another installed major
- or an existing system cluster cannot be selected by accident. It installs
- the extensions, bootstraps the admin user and starts the gateway — the
- package install above on its own does not leave a reachable endpoint. It
- prompts for the admin password. For automation, use the complete{" "}
-
- unattended setup
- {" "}
- instructions.
-
-
-
- Sample data is opt-in. After installing{" "}
- mongosh, add{" "}
- --load-sample-data to seed the{" "}
- StoreData database with 41,505 stores
- and 2 ratings. The command above leaves the new instance empty.
-
-
- The gateway then listens on port{" "}
- 10260. It binds all interfaces by
- default, so firewall the port before exposing it to a network. For existing
- PostgreSQL clusters, real certificates, upgrades, reset, and other day-2
- tasks, use the{" "}
-
- operations guide
-
- .
-
- >
- ) : null}
- {packageFamily === "apt" ? (
+ {canInstall ? : (
+ Commands will appear after your selection and the published package set are confirmed.
+ )}
+ {family === "apt" ? (
Running in a clean Ubuntu container as root?
Run export DEBIAN_FRONTEND= noninteractive in the shell first
@@ -420,308 +264,224 @@ export default function PackagesPage() {
and the install hangs with no visible error.
) : null}
-
-
- {isFullStack
- ? "What gets installed"
- : "Need the MongoDB-compatible gateway?"}
-
- {isFullStack ? (
- <>
-
- A per-major DocumentDB install resolves five package names. Installing{" "}
- {selectedPackageNames} pulls in
- everything below; the optional documentdb{" "}
- meta package selects PostgreSQL 18.
-
-
- {packageRoles.map((entry) => (
-
-
- {entry.name}
-
- {entry.role}
-
- ))}
-
- >
- ) : (
-
- Use the Docker image for the fastest gateway-backed local setup. If you want a
- package-backed host install that still works with mongosh,
- the Linux package guide includes the exact non-root gateway follow-up commands
- and host build prerequisites.
-
- )}
-
-
-
- Full package install guide →
-
-
- >
- )}
-
+
-
-
-
- Current release package catalog
-
-
-
-
-
- Format
- Distributions
- Architectures
- PostgreSQL versions
- Package naming
- Version served
-
-
-
-
- APT
- Ubuntu 24.04 · ubuntu24
- amd64, arm64
- 17, 18
-
- documentdb-<pg>
-
- {release.metaVersion}
-
-
- RPM
-
- Rocky/Alma/CentOS Stream 9 or registered RHEL 9 ·{" "}
- rpm/rhel9
-
- x86_64, aarch64
- 17, 18
-
- documentdb-<pg>
-
- {release.metaRpmVersion}
-
-
-
-
- Compared with earlier releases, v0.116 reduces the hosted package matrix. The
- repository contains only package combinations attached to{" "}
-
- {release.tagName}
-
- . Other combinations remain build-on-demand targets in the source repository;
- see the{" "}
-
- packaging guide
- {" "}
- to build the package you need from the matching tag.
+
+ 2. Configure and start DocumentDB
+
+ The wizard creates a new private PostgreSQL instance for major {pg}, configures the extensions,
+ creates your admin login, and starts the gateway and services at boot. It asks for the admin
+ password in your terminal. Keep that password for the connection step.
-
- Use Package Finder above to generate the exact command for your selected
- target, or see the{" "}
-
- Linux Packages Quick Start
- {" "}
- for the supported repository components and install commands written out in full.
+ {canInstall && }
+
+ The gateway listens on port 10260 on all interfaces by default. Restrict that port with your
+ firewall before setup. Use trusted TLS certificates before exposing it beyond local development.
-
-
-
-
-
- Migrating from repository targets retired in v0.116
-
-
-
- documentdb.io no longer publishes packages for Ubuntu 22.04, Debian 11/12/13,
- RHEL-compatible 8, or PostgreSQL 16. Existing installations keep running, but
- they receive no package updates and cannot reinstall those packages from the
- documentdb.io repository.
-
-
- Empty signed metadata remains at the retired repository URLs so{" "}
- apt update and{" "}
- dnf makecache do not break unrelated
- package operations. Remove the DocumentDB source if that host will not move to
- the current matrix:
-
-
-
sudo rm -f /etc/apt/sources.list.d/documentdb.list && sudo apt update
-
- sudo rm -f /etc/yum.repos.d/documentdb.repo && sudo dnf clean all
-
-
-
- To remain on an older target, use the matching GitHub release assets or build
- from that release tag. Those paths are not part of the current hosted support
- matrix.
-
-
-
-
-
-
- Version pinning and listing available versions
-
-
-
- Use the commands below to discover available versions before pinning, and pin{" "}
- {selectedPackageNames} — the package your
- selected target actually installs.
-
-
- APT and RPM use different version syntax, and individual subpackages can carry
- different release suffixes. Always copy the exact version returned below for{" "}
- {selectedPackageNames}; do not infer it
- from the extension or another package.
+
+ Need automation? Follow the complete{" "}
+ unattended setup{" "}
+ instructions. Already managing PostgreSQL? Use the{" "}
+ operations guide{" "}
+ instead of creating a new instance.
-
-
APT — list then pin
-
-
- apt-cache madison {selectedPackageNames}
-
-
-
-
- sudo apt install {selectedPackageNames}=<VERSION>
-
-
-
-
-
RPM — list then pin
-
-
- dnf --showduplicates list {selectedPackageNames}
-
-
-
-
- sudo dnf install {selectedPackageNames}-<VERSION>
-
-
-
-
- See all releases and release notes on{" "}
+
+ >
+ ) : (
+ <>
+
+ {dockerSetups.map((item) => (
+ setDockerSetup(item.value)}
+ className={`min-h-14 rounded-lg px-4 py-3 text-left text-sm font-semibold transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400 ${
+ dockerSetup === item.value ? "bg-neutral-700 text-white" : "text-gray-300 hover:text-white"
+ }`}
+ >
+ {item.title}
+ {item.description}
+
+ ))}
+
+ {dockerSetup === "guided" ? (
+
+ 1. Set up in VS Code
+
+ Install and start Docker first. The VS Code extension creates your local database,
+ generates credentials, and saves a connection.
+
- GitHub Releases
+ Set up in VS Code
- .
-
+
+ Don't have VS Code?{" "}
+ Download it first.
+
+
2. Run your first query
+
+ When setup finishes, select Open Connection. Then follow the{" "}
+ VS Code quickstart{" "}
+ to add a document and read it back.
+
+
+ ) : (
+
+ 1. Start a Docker container
+
+ Install and start Docker first. Replace both credential placeholders before running the
+ command. This local example exposes port 10260 only on your machine's loopback interface.
+
+ {selectionReady && }
+
+ The container initializes the database; do not run the Linux package setup wizard inside it.
+ For persistent volumes and a versioned image, follow the{" "}
+ Docker quickstart.
+
+
+ )}
+ >
+ )}
+
+ {!(method === "docker" && dockerSetup === "guided") && (
+
+ {method === "packages" ? "3" : "2"}. Connect and run your first query
+
+ Install{" "}
+ mongosh {" "}
+ separately, then connect from the same host as DocumentDB.{" "}
+ {method === "packages" ? "Use the admin password you chose during setup." : "Use the username and password you chose for Docker."}{" "}
+ The shell prompts for the password; it is not included in the connection URI.
+
+ {selectionReady && (method === "docker" || canInstall) && (
+ <>
+
+ In mongosh, insert a document and read it back:
+
+ >
+ )}
+
+ Expect an acknowledged insert and a document containing "Hello, DocumentDB!".
+ The example uses the mydb database. The self-signed certificate bypass is
+ for local development only; use trusted certificates and remove the bypass for other deployments.
+
+
+ {nextGuides.map((guide) => (
+
+ {guide.title}
+ {guide.description}
+
+ ))}
-
+
+ )}
-
-
- Direct package downloads
-
-
-
- Individual .deb and{" "}
- .rpm files are attached to each release on
- GitHub. Recent release examples:
-
-
-
{currentReleaseExamples[0]}
-
{currentReleaseExamples[1]}
-
{currentReleaseExamples[2]}
-
-
- Choose an asset whose PostgreSQL version and architecture match your host.
-
-
- Browse releases on GitHub →
-
+ {method === "packages" && (
+
+ Keep control after the first query
+
+ Your private database lives under /var/lib/documentdb-local/{pg}/data.
+ The per-major package uses documentdb-local@{pg}.target for service management.
+ A restart preserves your data.
+
+ {canInstall && }
+
+ Sample data is optional. After installing mongosh, add{" "}
+ --load-sample-data to seed the{" "}
+ StoreData database when running setup. The default setup leaves your new instance empty.
+
+
+
+ Use your existing local PostgreSQL
+ Keep its lifecycle under your control. Review configuration changes and restart requirements first. Remote/cloud-managed PostgreSQL is not supported by this packaged flow.
+
+
+ Install only the PostgreSQL extension
+ Use the SQL-facing capabilities without installing a gateway. Extension-only installation does not create a MongoDB-compatible endpoint.
+
-
+
+ See the operations guide{" "}
+ for logs, TLS, user management, and cleanup. Removing packages or using{" "}
+ --restore does not erase database data.
+
+
+ )}
-
-
- Troubleshooting quick checks
-
-
-
-
- sudo apt update && apt search documentdb && apt-cache policy
- postgresql-18-documentdb
-
-
-
-
- sudo dnf clean all && dnf search documentdb && rpm -qi
- postgresql18-documentdb
-
+
+
+ All downloads and package details
+
+ Browse GitHub release assets {" "}
+ for individual DEB/RPM files, checksums, and the package inventory. Select the matching distribution,
+ PostgreSQL major, and architecture; install the matching package set together.
+
+
+ The optional documentdb meta package selects PostgreSQL 18 and adds the public{" "}
+ documentdb-local.target alias. The commands above install the explicit per-major
+ package instead.
+
+
+ {packageRoles.map((entry) => (
+
+
{entry.name}
+ {entry.role}
+
+ ))}
+
+
+ Other OS/PostgreSQL combinations are build-on-demand targets, not current hosted packages.
+ See the {releaseStatus === "live" ? "matching release packaging guide" : "reference release packaging guide"} .
+ PostgreSQL 15 is extension-only for Linux packages.
+
+
+
+ Available versions and retired targets
+
+ For fresh installs, list available versions before pinning. APT and RPM use different version
+ syntax, and individual subpackages can carry different release suffixes. Use the version
+ reported for {selectedPackageNames}, not the extension's version.
+
+ {selectionReady && (
+
+
-
+ )}
+
+ The hosted matrix was reduced in v0.116. Ubuntu 22.04, Debian 11/12/13, EL8, and
+ PostgreSQL 16 packages are no longer served here. Existing installations are not
+ automatically migrated, and do not receive package updates from these retired targets.
+ Empty signed repository metadata remains so unrelated package operations continue to work.
+
+
+ Use matching older release assets or build from that source tag if you must stay on a
+ retired target. For a current installation, use a clean supported host. In-place upgrades
+ from earlier releases are not supported.
+
-
-
-
-
-
- 3. Connect and try it
-
-
- Docker starts a gateway-backed local endpoint on port 10260. On Ubuntu 24.04 and
- EL9 the packages give you the same thing: install, then run{" "}
-
- {buildSetupCommand(packageFamily === "apt" ? aptPgVersion : rpmPgVersion)}
-
- {", "}which creates a private database instance for the selected PostgreSQL major and
- starts the gateway.
+
+ Troubleshooting and manual instructions
+
+ Dependency errors: run the complete repository setup command, including PGDG and the distribution prerequisites.
+ Port already in use: select an explicit alternate port using the operations guide. Do not stop an unrelated service.
+ Cannot connect: confirm setup finished, services are active, and you are using the right host, credentials, and TLS settings.
+ Missing shell: mongosh is not included in the Linux package set; install it separately.
+ Uninstalling is not a reset: data deletion is a separate, explicit operation.
+
+
+ Complete Linux quickstart
+ {" · "} Advanced operations
+ {" · "} Docker quickstart
-
-
-
- {nextGuides.map((guide) => (
-
-
- {guide.title}
-
-
{guide.description}
-
- ))}
-
-
-
-
- Linux package guide
-
-
- All docs
-
-
+
diff --git a/app/page.tsx b/app/page.tsx
index dc1b157..f014430 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -330,7 +330,7 @@ export default function Home() {
href="/packages"
className="inline-flex w-full items-center justify-center rounded-md border border-blue-400 bg-blue-500/10 px-6 py-3 text-sm font-semibold text-blue-200 transition-colors hover:bg-blue-500/20 sm:w-auto"
>
- Download
+ Install & Download
' \\
@@ -111,6 +113,14 @@ use StoreData
db.stores.find({}, { _id: 0, name: 1, city: 1, "sales.revenue": 1 }).limit(3)
\`\`\`
+Write and read back your own document; this does not require sample data:
+
+\`\`\`javascript
+use quickstart
+db.orders.insertOne({ item: "widget", qty: 5 })
+db.orders.find({ item: "widget" })
+\`\`\`
+
If you prefer certificate validation instead of \`--tlsAllowInvalidCertificates\`, follow the certificate steps in [DocumentDB Local](/docs/documentdb-local).
## Persistence and initialization
@@ -163,35 +173,22 @@ If something does not work as expected:
- [DocumentDB Local](/docs/documentdb-local)
- [Samples Gallery](/samples)
- [Linux Packages Quick Start](/docs/getting-started/packages)
-- [Package Finder](/packages)
+- [Install DocumentDB](/packages?method=packages)
`;
export const linuxPackagesGuideContent = `# Linux Packages Quick Start
Install DocumentDB from the published package repository and get a MongoDB-compatible endpoint on your own host.
-The current official release publishes the full stack — extension, gateway, setup wizard and systemd units — for **Ubuntu 24.04 and EL9, on PostgreSQL 17 or 18**. EL9 includes Rocky Linux, AlmaLinux, CentOS Stream, and registered Red Hat Enterprise Linux; the Package Finder supplies the prerequisite command for each family. Starting with v0.116, this is a deliberately smaller prebuilt matrix than earlier releases. The website repository mirrors only the current release assets and does not carry older packages forward to make other targets appear current.
-
-> [!NOTE]
-> Need another distribution or PostgreSQL major? We welcome community builds. Check out the matching release tag and use the version-parameterized [packaging scripts](https://github.com/documentdb/documentdb/blob/v0.117-0/packaging/README.md). \`build_packages.sh\` builds the extension, \`gateway/build_gateway_packages.sh\` builds the gateway, and \`build_extra_packages.sh\` builds the common, tools, stand-alone, and meta packages. PostgreSQL 15 is extension-only because the setup tools require PostgreSQL 16 or newer. These builds are on demand and are not official release assets hosted by documentdb.io.
-
-## If you used an earlier repository target
-
-documentdb.io no longer publishes packages for Ubuntu 22.04, Debian 11/12/13, RHEL-compatible 8, or PostgreSQL 16. Existing installations keep running, but receive no package updates and cannot reinstall those packages from documentdb.io.
-
-Empty signed metadata remains at the retired repository URLs so \`apt update\` and \`dnf makecache\` continue to work. Remove the source on a host that will not move to the current matrix:
+The current official release publishes the full stack — extension, gateway, setup wizard and systemd units — for **Ubuntu 24.04 and EL9, on PostgreSQL 17 or 18, amd64 or arm64**. EL9 includes Rocky Linux, AlmaLinux, CentOS Stream, and registered Red Hat Enterprise Linux; [Linux packages installation](/packages?method=packages) supplies the prerequisite command for each family. Starting with v0.116, this is a deliberately smaller prebuilt matrix than earlier releases. The website repository mirrors only the current release assets and does not carry older packages forward to make other targets appear current.
-\`\`\`bash
-# Debian / Ubuntu
-sudo rm -f /etc/apt/sources.list.d/documentdb.list
-sudo apt update
+**Recommended:** install the complete stack, then create a new private PostgreSQL 18 instance. The commands detect architecture on the Linux host where you run them. For containers or macOS/Windows evaluation, choose [Docker installation](/packages?method=docker).
-# RHEL-compatible
-sudo rm -f /etc/yum.repos.d/documentdb.repo
-sudo dnf clean all
-\`\`\`
+> [!IMPORTANT]
+> This pre-GA release supports **fresh installation only**, not in-place package upgrades from earlier releases. Use a clean host or a new, empty PostgreSQL instance. Removing packages preserves database files; reinstalling is not a data reset.
-To remain on an older target, use its GitHub release assets or build from the matching source tag. Neither path is part of the current hosted support matrix.
+> [!NOTE]
+> Need another distribution or PostgreSQL major? We welcome community builds. Check out the matching release tag and use the version-parameterized [packaging scripts](https://github.com/documentdb/documentdb/blob/v0.117-0/packaging/README.md). \`build_packages.sh\` builds the extension, \`gateway/build_gateway_packages.sh\` builds the gateway, and \`build_extra_packages.sh\` builds the common, tools, stand-alone, and meta packages. PostgreSQL 15 is extension-only because the setup tools require PostgreSQL 16 or newer. These builds are on demand and are not official release assets hosted by documentdb.io.
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.
@@ -218,7 +215,7 @@ This command requires an active Red Hat subscription. RHEL exposes CodeReady Bui
${buildRpmInstallCommand('rhel9', 'auto', '18')}
\`\`\`
-For PostgreSQL 17, install \`documentdb-17\`; there is no \`documentdb-16\`. Both EL9 flows enable CodeReady Builder, which supplies \`libqhull_r.so.7\` for PostGIS dependencies.
+For PostgreSQL 17, select it in [Linux packages installation](/packages?method=packages) to generate matching install and setup commands for \`documentdb-17\`; there is no \`documentdb-16\`. Both EL9 flows enable CodeReady Builder, which supplies \`libqhull_r.so.7\` for PostGIS dependencies.
Then install \`mongosh\`, which you need to talk to the endpoint:
@@ -248,18 +245,19 @@ It creates a new private PostgreSQL 18 instance, installs the extensions, starts
Sample data is opt-in. Add \`--load-sample-data\` to the setup command to seed the \`StoreData\` database with 41,505 documents in \`stores\` and 2 documents in \`ratings\`. This requires \`mongosh\`; the command above leaves the new instance empty.
-For automation, use the complete [unattended setup](/docs/linux-packages#unattended-setup) command. To adopt an existing PostgreSQL instance instead, follow [Adopt an existing PostgreSQL instance](/docs/linux-packages#adopt-an-existing-postgre-sql-instance); brownfield setup intentionally has different lifecycle and restart requirements.
+For automation, use the complete [unattended setup](/docs/linux-packages#unattended-setup) command. To use PostgreSQL you already manage on this host, follow [Adopt an existing PostgreSQL instance](/docs/linux-packages#adopt-an-existing-postgre-sql-instance); it changes configuration and may require an administrator-controlled restart. For SQL-only use without a gateway, see [Install the PostgreSQL extension only](/docs/linux-packages#install-the-postgre-sql-extension-only).
-Now open a shell against the endpoint:
+Now open a shell against the endpoint. The password prompt uses the admin password you chose during setup. The self-signed certificate bypass is for **local development only**; use a trusted certificate for network access.
\`\`\`bash
-mongosh localhost:10260 -u admin -p '' --authenticationMechanism SCRAM-SHA-256 \\
+mongosh localhost:10260 -u admin -p --authenticationMechanism SCRAM-SHA-256 \\
--tls --tlsAllowInvalidCertificates
\`\`\`
A database and collection are created on first write:
\`\`\`javascript
+> use quickstart
> db.orders.insertOne({ item: "widget", qty: 5 })
{ acknowledged: true, insertedId: ObjectId('...') }
@@ -274,17 +272,35 @@ 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)
-- Choose between the published distributions, architectures and PostgreSQL majors: [Package Finder](/packages)
+- Choose between the published distributions, architectures and PostgreSQL majors: [Linux packages installation](/packages?method=packages)
## Troubleshooting
-- \`Unable to locate package documentdb-18\` (apt) / \`No match for argument: documentdb-18\` (dnf) — the DocumentDB repository was not added, or the host is not in the current release matrix. Check the [Package Finder](/packages)
+- \`Unable to locate package documentdb-18\` (apt) / \`No match for argument: documentdb-18\` (dnf) — the DocumentDB repository was not added, or the host is not in the current release matrix. Check [Linux packages installation](/packages?method=packages)
- \`documentdb-18 : Depends: postgresql-18 but it is not installable\` — PGDG was not added first
- \`nothing provides libqhull_r.so.7\` — CRB or CodeReady Builder was not enabled for the selected EL9 family
- \`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 hosts without systemd: [Operating a package install](/docs/linux-packages#troubleshooting).
+
+## If you used an earlier repository target
+
+documentdb.io no longer publishes packages for Ubuntu 22.04, Debian 11/12/13, RHEL-compatible 8, or PostgreSQL 16. Existing installations keep running, but receive no package updates and cannot reinstall those packages from documentdb.io.
+
+Empty signed metadata remains at the retired repository URLs so \`apt update\` and \`dnf makecache\` continue to work. Remove the source on a host that will not move to the current matrix:
+
+\`\`\`bash
+# Debian / Ubuntu
+sudo rm -f /etc/apt/sources.list.d/documentdb.list
+sudo apt update
+
+# RHEL-compatible
+sudo rm -f /etc/yum.repos.d/documentdb.repo
+sudo dnf clean all
+\`\`\`
+
+To remain on an older target, use its GitHub release assets or build from the matching source tag. Neither path is part of the current hosted support matrix.
`;
export const linuxPackagesOperationsContent = `# Operating a package install
@@ -345,8 +361,8 @@ sudo systemctl stop documentdb-local@18.target
## Adopt an existing PostgreSQL instance
-Use brownfield mode only when PostgreSQL already exists and its service and data remain
-operator-owned. Back up the instance first. The wizard does not create, delete, start, or stop
+Use this mode only when PostgreSQL already exists **locally on the gateway host** and its service and data remain
+operator-owned; remote PostgreSQL adoption is not supported. You need administrator access to change PostgreSQL configuration and restart its service. Back up the instance first. The wizard does not create, delete, start, or stop
that PostgreSQL instance, but it does add managed configuration blocks, create the gateway role,
install the DocumentDB extensions, and register the gateway.
@@ -368,6 +384,18 @@ The wizard's default \`default_toast_compression\` setting applies to newly writ
every database on an adopted instance. If other workloads must retain PostgreSQL's own default,
prefix both setup runs with \`sudo DOCUMENTDB_TOAST_COMPRESSION=default\`.
+## Install the PostgreSQL extension only
+
+Choose this advanced path for SQL-facing DocumentDB capabilities in PostgreSQL you manage.
+It does **not** create a MongoDB-compatible network endpoint, install the gateway, or run
+\`documentdb-setup\`. Shell, driver, and VS Code quick starts require the complete stack instead.
+
+Use the extension package for your PostgreSQL major: \`postgresql-N-documentdb\` on Ubuntu
+or \`postgresqlN-documentdb\` on EL9. You own PostgreSQL configuration, extension activation,
+and service restarts. Follow the matching release's [manual package instructions](https://github.com/documentdb/documentdb/blob/v0.117-0/packaging/README.md),
+or the [extension-only offline instructions](/docs/linux-packages/offline#smaller-offline-cases)
+when PostgreSQL and all extension dependencies are already installed.
+
## Running SQL against a package-managed private instance
A greenfield PostgreSQL instance runs as the \`documentdb-local\` user on a socket, so a bare
@@ -618,6 +646,32 @@ If the target already has PostgreSQL, the PGDG extension dependencies (\`postgre
- **Full stack from the release assets** — pass the five packages for the selected PostgreSQL major to a *single* \`apt install\` / \`dnf install\`: \`documentdb-N\`, the matching \`postgresql-N-documentdb\` / \`postgresqlN-documentdb\` extension, \`documentdb-common\`, \`documentdb-gateway\`, and \`documentdb-postgresql-tools\`. For PostgreSQL 18 only, the optional \`documentdb\` meta package may be included; it selects \`documentdb-18\`. Local files resolve dependencies only against enabled repositories, so a package whose dependencies are not included still fails.
`;
+const clientInstancePrerequisiteContent = `## Have a running DocumentDB instance?
+
+If yes, keep it and continue with the client prerequisites below. Otherwise, choose one server installation:
+
+- [Docker](/packages?method=docker): run a local container on Linux, macOS, or Windows. Recommended for evaluation and development.
+- [Linux packages](/packages?method=packages): install the complete stack, then create a private PostgreSQL instance with the setup wizard.
+
+The [Docker Quick Start](/docs/getting-started/docker) and [Linux Packages Quick Start](/docs/getting-started/packages) include the full server instructions. Do not start a second instance if one is already running.
+
+These examples connect to \`localhost:10260\`, so run the client on the same host as DocumentDB. Use the credentials chosen for Docker, or username \`admin\` and the password chosen during Linux package setup. If you changed the endpoint, use its configured host and port.
+
+Self-signed certificate bypasses below are for **local development only**. For network access, use a trusted certificate. Linux package setup binds the gateway on **all interfaces** by default: firewall port \`10260\` before setup and follow [network and certificate guidance](/docs/linux-packages#before-exposing-it-to-a-network). Docker examples publish only on loopback.
+`;
+
+const driverCredentialsContent = `## Set your client credentials
+
+Set these in the terminal that will run your application. Replace the placeholders with your existing instance's credentials (for Linux packages, \`admin\` and your setup password). The driver passes them as raw values, not embedded in a connection URI.
+
+\`\`\`bash
+export DOCUMENTDB_USERNAME=''
+export DOCUMENTDB_PASSWORD=''
+\`\`\`
+`;
+
+const optionalSampleDataContent = `Sample data is **opt-in**, not required for your first insert and read. Linux package installations can add \`--load-sample-data\` during setup, which separately requires [mongosh](https://www.mongodb.com/docs/mongodb-shell/install/). Docker installations can start with \`--init-data true\`. Without these options, \`StoreData\` does not exist. Existing Docker volumes are not migrated automatically; do not delete data you need just to load a sample.`;
+
const vscodeQuickStartGuideContent = `# Visual Studio Code Quick Start
Use DocumentDB for VS Code to set up a local DocumentDB instance, browse sample data, and create your first database without leaving the editor.
@@ -686,7 +740,7 @@ Use this for a DocumentDB instance that is already running. You only add a conne
2. In the local connection area, select **DocumentDB Local** and start the **New Local Connection** flow.
3. Enter your instance's port (\`10260\` for the command above), username, and password.
4. At the TLS/SSL prompt:
- - Choose **Disable TLS/SSL (Not recommended)** if you are using the default self-signed local setup and have not configured trust for the certificate yet.
+ - For **local development only**, choose **Disable TLS/SSL (Not recommended)** if you are using the default self-signed local setup and have not configured trust for the certificate yet.
- Keep **Enable TLS/SSL (Default)** if you already configured a trusted local certificate.
5. Finish the wizard and confirm the new connection appears in the connections tree.
@@ -730,7 +784,7 @@ If setup or the connection does not work on the first try:
- Verify the extension is installed and reload VS Code if the DocumentDB view does not appear
- Confirm your local DocumentDB instance is actually running before you connect
- If you used Docker, check \`docker ps\` and \`docker logs documentdb\`
-- If you used a host-built gateway, confirm the gateway process is running and listening on the port you entered
+- If you used Linux packages, check \`sudo documentdb-setup --status\`; for a manually built gateway, confirm its process is listening on the port you entered
- If the local connection wizard fails on security, retry and choose the TLS/SSL option that matches your certificate setup
- Use \`mongosh\` to confirm the endpoint works independently of VS Code
@@ -757,14 +811,19 @@ const nodejsGuideContent = `# Node.js Quick Start
Connect to DocumentDB from Node.js using the official MongoDB driver.
+${clientInstancePrerequisiteContent}
+
## Prerequisites
- Node.js 20.19 or later (required by the current \`mongodb\` driver)
- npm
-- [Docker](https://www.docker.com/)
- Basic familiarity with JavaScript
-## Start DocumentDB Local
+${driverCredentialsContent}
+
+## Optional: start a Docker instance
+
+Skip this if you installed Linux packages or already have a running instance. If you chose Docker and have [Docker](https://www.docker.com/) installed, replace the placeholders below with your chosen credentials. This self-contained command also sets the environment variables read by your application:
\`\`\`bash
export DOCUMENTDB_USERNAME=''
@@ -777,12 +836,7 @@ docker run -dt --name documentdb \\
--password "\${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD}"
\`\`\`
-> Replace the placeholder values before running the command. The Node.js process below
-> reads the same two environment variables, so the credentials are passed as raw values
-> rather than embedded in a URI.
->
-> DocumentDB Local uses a self-signed certificate by default, so the quickest local
-> Node.js connection uses \`tlsAllowInvalidCertificates=true\`.
+Wait for the readiness banner in \`docker logs documentdb\` before connecting; see [Docker Quick Start](/docs/getting-started/docker#verify-the-container).
## Create a project
@@ -795,7 +849,7 @@ npm install mongodb
## Connect and run your first queries
-Create an \`index.js\` file:
+Create an \`index.js\` file. The certificate bypass is for **local development only**, with the default self-signed certificate from Linux package setup or Docker.
\`\`\`javascript
const { MongoClient } = require("mongodb");
@@ -863,9 +917,7 @@ node index.js
## Connect with a trusted local certificate instead
-If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`,
-copy the generated certificate from the container, then replace the \`options\` object
-above with the trusted-certificate version below.
+If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`, obtain the trusted certificate or CA file for your endpoint and replace the original \`options\` object with the version below. For Linux packages, follow [certificate configuration](/docs/linux-packages#before-exposing-it-to-a-network). For Docker, copy the local certificate with:
\`\`\`bash
docker cp documentdb:/home/documentdb/.local/state/documentdb-gateway/tls/cert.pem ~/documentdb-cert.pem
@@ -893,16 +945,19 @@ const pythonQuickStartContent = `# Python Quick Start
Use PyMongo to connect to DocumentDB, verify authentication and TLS, and run your first document queries from Python.
+${clientInstancePrerequisiteContent}
+
## Prerequisites
- Python 3.9 or later
- pip
-- A local DocumentDB instance from [Docker Quick Start](/docs/getting-started/docker) or [Linux Packages Quick Start](/docs/getting-started/packages)
- Optional: [mongosh](https://www.mongodb.com/docs/mongodb-shell/install/) for independent connection checks
-## Start DocumentDB first
+${driverCredentialsContent}
+
+## Optional: start a Docker instance
-For the fastest local setup, start DocumentDB Local with Docker:
+Skip this if you installed Linux packages or already have a running instance. If you chose Docker and have [Docker](https://www.docker.com/) installed, replace the placeholders below with your chosen credentials. This self-contained command also sets the environment variables read by your application:
\`\`\`bash
export DOCUMENTDB_USERNAME=''
@@ -915,14 +970,7 @@ docker run -dt --name documentdb \\
--password "\${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD}"
\`\`\`
-If you prefer a host installation instead of Docker, use the [Linux Packages Quick Start](/docs/getting-started/packages) on a distribution in the current release matrix.
-
-> Replace the placeholder values before running the command. The Python process below
-> reads the same two environment variables, so the credentials are passed as raw values
-> rather than embedded in a URI.
->
-> DocumentDB Local uses a self-signed certificate by default, so the quickest local
-> PyMongo connection uses \`tlsAllowInvalidCertificates=true\`.
+Wait for the readiness banner in \`docker logs documentdb\` before connecting; see [Docker Quick Start](/docs/getting-started/docker#verify-the-container).
## Create a virtual environment (optional)
@@ -943,7 +991,7 @@ python -m pip install pymongo
## Connect and run your first queries
-Create a \`quickstart.py\` file:
+Create a \`quickstart.py\` file. The certificate bypass is for **local development only**, with the default self-signed certificate from Linux package setup or Docker.
\`\`\`python
import os
@@ -1003,7 +1051,9 @@ You should see the recent movie documents printed after a successful \`ping\`.
## Explore the built-in sample data
-Sample data is **opt-in** — this needs a container started with \`--init-data true\`. Without it \`StoreData\` does not exist and the query returns nothing. Add this snippet after \`client.admin.command("ping")\`:
+${optionalSampleDataContent}
+
+If you loaded the sample, add this snippet after \`client.admin.command("ping")\`:
\`\`\`python
for store in client["StoreData"]["stores"].find(
@@ -1015,7 +1065,7 @@ for store in client["StoreData"]["stores"].find(
## Use a trusted local certificate instead
-If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`, copy the generated certificate from the container, then replace the \`MongoClient\` call above with the trusted-certificate version below.
+If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`, obtain the trusted certificate or CA file for your endpoint and replace the original \`MongoClient\` call with the version below. For Linux packages, follow [certificate configuration](/docs/linux-packages#before-exposing-it-to-a-network). For Docker, copy the local certificate with:
\`\`\`bash
docker cp documentdb:/home/documentdb/.local/state/documentdb-gateway/tls/cert.pem ~/documentdb-cert.pem
@@ -1038,7 +1088,7 @@ If the Python quick start does not work on the first try:
- Verify your local DocumentDB instance is running before you start Python
- If you used Docker, check \`docker ps --filter "name=documentdb"\` and \`docker logs documentdb\`
-- If you used a host-built gateway, confirm the gateway process is running and listening on port \`10260\`
+- If you used Linux packages, check \`sudo documentdb-setup --status\`; for a manually built gateway, confirm its process is listening on port \`10260\`
- If Python cannot import \`pymongo\`, verify the active interpreter with \`python -c "import sys; print(sys.executable)"\` and reinstall with \`python -m pip install pymongo\`
- If you see TLS or certificate errors, either use the default local self-signed flow with \`tlsAllowInvalidCertificates=true\` or switch to a trusted local certificate with \`tlsCAFile\`
- Use [Mongo Shell Quick Start](/docs/getting-started/mongo-shell-quickstart) to validate the endpoint independently of your application code
@@ -1057,15 +1107,16 @@ const mongoShellQuickStartContent = `# Mongo Shell Quick Start
Use \`mongosh\` to verify a local DocumentDB instance, inspect sample data, and run your first document commands.
+${clientInstancePrerequisiteContent}
+
## Prerequisites
- [mongosh](https://www.mongodb.com/docs/mongodb-shell/install/)
-- A local DocumentDB instance from [Docker Quick Start](/docs/getting-started/docker) or [Linux Packages Quick Start](/docs/getting-started/packages)
-- A local port available for DocumentDB (the examples use \`10260\`)
+- Your instance's endpoint and credentials (the examples use \`localhost:10260\`)
-## Start DocumentDB first
+## Optional: start a Docker instance
-For the fastest local setup, start DocumentDB Local with Docker:
+Skip this if you installed Linux packages or already have a running instance. If you chose Docker and have [Docker](https://www.docker.com/) installed:
\`\`\`bash
docker run -dt --name documentdb \\
@@ -1075,14 +1126,12 @@ docker run -dt --name documentdb \\
--password ''
\`\`\`
-If you prefer a host installation instead of Docker, use the [Linux Packages Quick Start](/docs/getting-started/packages) on a distribution in the current release matrix.
-
-> Replace \`\` and \`\` with your own credentials.
->
-> DocumentDB Local starts **empty** — pass \`--init-data true\` on the \`docker run\` above to seed the \`StoreData\` sample data used below. It also uses a self-signed certificate by default, so the fastest local \`mongosh\` connection adds \`--tlsAllowInvalidCertificates\`.
+Replace the placeholders with your own credentials. Wait for the readiness banner in \`docker logs documentdb\` before connecting; see [Docker Quick Start](/docs/getting-started/docker#verify-the-container).
## Connect and verify the connection
+Use your existing instance's credentials. The certificate bypass is for **local development only** with a self-signed certificate, whether you used Docker or installed Linux packages.
+
\`\`\`bash
mongosh localhost:10260 \\
-u '' \\
@@ -1104,7 +1153,9 @@ Successful output confirms authentication, TLS, and the gateway endpoint are wor
## Explore the built-in sample data
-Sample data is **opt-in**: this section needs a container started with \`--init-data true\`. Without it \`StoreData\` does not exist and these queries return nothing.
+${optionalSampleDataContent}
+
+If you did not load the sample, skip directly to **Create your own collection** below.
\`\`\`javascript
use StoreData
@@ -1140,12 +1191,15 @@ db.movies.find(
## Use a trusted local certificate instead
-If you want certificate validation instead of \`--tlsAllowInvalidCertificates\`, copy
-the generated certificate from the container and pass it to \`mongosh\`.
+If you want certificate validation instead of \`--tlsAllowInvalidCertificates\`, obtain the trusted certificate or CA file for your endpoint. For Linux packages, follow [certificate configuration](/docs/linux-packages#before-exposing-it-to-a-network). For Docker, copy the local certificate with:
\`\`\`bash
docker cp documentdb:/home/documentdb/.local/state/documentdb-gateway/tls/cert.pem ~/documentdb-cert.pem
+\`\`\`
+Then pass your certificate file to \`mongosh\`:
+
+\`\`\`bash
mongosh localhost:10260 \\
-u '' \\
-p '' \\
@@ -1160,7 +1214,7 @@ If \`mongosh\` does not connect on the first try:
- Verify the local DocumentDB instance is running before you connect
- If you used Docker, check \`docker ps --filter "name=documentdb"\` and \`docker logs documentdb\`
-- If you used a host-built gateway, confirm the gateway process is running and listening on port \`10260\`
+- If you used Linux packages, check \`sudo documentdb-setup --status\`; for a manually built gateway, confirm its process is listening on port \`10260\`
- If authentication fails, confirm the username and password you used when you started DocumentDB
- If TLS validation fails, either keep \`--tlsAllowInvalidCertificates\` for the default local self-signed setup or switch to \`--tlsCAFile\` with a trusted certificate
- If \`mongosh\` is not installed, follow the [mongosh install guide](https://www.mongodb.com/docs/mongodb-shell/install/)
@@ -1250,26 +1304,29 @@ Together, these components let you use DocumentDB through MongoDB-compatible too
const gettingStartedIndexStartHereContent = `## Start here
-If you're new to DocumentDB, use this order:
+Choose your environment once, create a working instance, then connect with the client that fits your goal:
+
+1. **Choose Docker or Linux packages.** [Docker installation](/packages?method=docker) is recommended for evaluation and development on Linux, macOS, or Windows. [Linux packages installation](/packages?method=packages) is for environments without Docker, or when you need control over PostgreSQL, topology, services, and configuration.
+2. **Create a working instance.** Follow the [Docker Quick Start](/docs/getting-started/docker) or [Linux Packages Quick Start](/docs/getting-started/packages). Linux package installation has two stages: install packages, then run the setup wizard. Neither copying a command nor installing files alone proves the endpoint is ready.
+3. **Insert and read your first document.** Use the [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), or [Visual Studio Code Quick Start](/docs/getting-started/vscode-quickstart). Keep the same running instance; no second server installation is needed.
-1. [Docker Quick Start](/docs/getting-started/docker) - Fastest local install for evaluation and development
-2. [Mongo Shell Quick Start](/docs/getting-started/mongo-shell-quickstart) - Verify connectivity, authentication, and your first queries
-3. [Node.js Quick Start](/docs/getting-started/nodejs-setup) or [Python Quick Start](/docs/getting-started/python-setup) - Connect from an application driver
-4. [Linux Packages Quick Start](/docs/getting-started/packages) or the [Package Finder](/packages) - Use this when you need a persistent Linux installation instead of Docker
+Linux packages are pre-GA and support **fresh installation only**, not in-place upgrades from earlier releases. Removing packages preserves database files; reinstalling does not reset data.
-If you prefer an editor-first workflow, start with the [Visual Studio Code Quick Start](/docs/getting-started/vscode-quickstart).
+For advanced control, [use an existing local PostgreSQL instance](/docs/linux-packages#adopt-an-existing-postgre-sql-instance) with administrator-managed configuration and restart, or [install the PostgreSQL extension only](/docs/linux-packages#install-the-postgre-sql-extension-only). Extension-only installation does not create a MongoDB-compatible endpoint.
`;
const gettingStartedIndexVerificationContent = `## Verify your setup
-Before moving on to application code, confirm that DocumentDB is reachable and you can run a simple query.
+Before moving on to application code, confirm that DocumentDB is reachable and can insert and read a document. For Docker, check \`docker ps --filter "name=documentdb"\` and wait for the readiness banner in \`docker logs documentdb\`; for Linux packages, inspect \`sudo documentdb-setup --status\`.
-\`\`\`bash
-docker ps --filter "name=documentdb"
+Install [mongosh](https://www.mongodb.com/docs/mongodb-shell/install/) separately for this shell example. Run it on the same host as DocumentDB. Use your Docker username, or \`admin\` for Linux packages, and enter your password at the prompt.
+
+The certificate bypass is for **local development only**. Linux package setup binds the gateway on **all interfaces** by default: firewall port \`10260\` before setup and follow [network and certificate guidance](/docs/linux-packages#before-exposing-it-to-a-network).
+\`\`\`bash
mongosh localhost:10260 \\
-u '' \\
- -p '' \\
+ -p \\
--authenticationMechanism SCRAM-SHA-256 \\
--tls \\
--tlsAllowInvalidCertificates
@@ -1279,8 +1336,13 @@ Then run:
\`\`\`javascript
db.runCommand({ ping: 1 })
+use quickstart
+db.orders.insertOne({ item: "widget", qty: 5 })
+db.orders.find({ item: "widget" })
\`\`\`
+The insert should report \`acknowledged: true\`, and the query should return your document. No sample-data loading is required.
+
For a fuller walkthrough, use the [Mongo Shell Quick Start](/docs/getting-started/mongo-shell-quickstart). Driver-based examples are available in the [Node.js Quick Start](/docs/getting-started/nodejs-setup) and [Python Quick Start](/docs/getting-started/python-setup).
`;
@@ -1288,11 +1350,11 @@ const gettingStartedIndexTroubleshootingContent = `## Troubleshooting and debugg
If setup does not work on the first try:
-- Confirm the container is running and port \`10260\` is published with \`docker ps\`.
-- Inspect startup, authentication, and TLS errors with \`docker logs documentdb\`.
-- If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`, follow the certificate steps in [DocumentDB Local](/docs/documentdb-local).
-- For more verbose local diagnostics, re-create DocumentDB Local with \`-e DOCUMENTDB_LOG_LEVEL=debug\` (the \`--log-level\` flag is currently a no-op); the available runtime options are documented in [DocumentDB Local](/docs/documentdb-local).
-- If you are installing on a host instead of Docker, use [Linux Packages Quick Start](/docs/getting-started/packages) or the [Package Finder](/packages) to get the correct apt or rpm flow.
+- For Linux packages, check \`sudo documentdb-setup --status\` and [package troubleshooting](/docs/getting-started/packages#troubleshooting). The default PostgreSQL 18 install uses \`documentdb-local@18.target\`, not the meta-package alias.
+- For Docker, confirm the container is running and port \`10260\` is published with \`docker ps\`. Inspect startup, authentication, and TLS errors with \`docker logs documentdb\`.
+- If you want certificate validation instead of \`tlsAllowInvalidCertificates=true\`, follow the Linux package [certificate steps](/docs/linux-packages#before-exposing-it-to-a-network) or [DocumentDB Local](/docs/documentdb-local) for Docker.
+- For more verbose Docker diagnostics, re-create DocumentDB Local with \`-e DOCUMENTDB_LOG_LEVEL=debug\` (the \`--log-level\` flag is currently a no-op); the available runtime options are documented in [DocumentDB Local](/docs/documentdb-local).
+- To change your installation choice, open [Docker installation](/packages?method=docker) or [Linux packages installation](/packages?method=packages).
`;
const gettingStartedIndexFeatureExplorationContent = `## Explore key features
@@ -1332,17 +1394,19 @@ const articleTitleOverrides: Record = {
const articleDescriptionOverrides: Record = {
'getting-started/index':
- 'Choose the fastest setup path for DocumentDB, verify your installation, and find troubleshooting and feature guides.',
+ 'Choose Docker or Linux packages, create a DocumentDB instance, and insert and read your first document with a shell, driver, or editor.',
+ 'getting-started/packages':
+ 'Install DocumentDB on Linux with Ubuntu APT or EL9 RPM/dnf packages, set up a private PostgreSQL instance, and run your first query.',
'getting-started/azure-setup':
'Deploy and manage DocumentDB on Microsoft Azure for a fully managed experience.',
'getting-started/vscode-quickstart':
- 'Install the VS Code extension, connect to DocumentDB Local, and verify your first editor-based workflow.',
+ 'Install the VS Code extension, connect to DocumentDB with Docker or Linux packages, and insert and read your first document.',
'getting-started/nodejs-setup':
- 'Start DocumentDB Local, connect with the MongoDB Node.js driver, and run your first queries.',
+ 'Connect to DocumentDB with Docker or Linux packages with the MongoDB Node.js driver and run your first queries.',
'getting-started/python-setup':
- 'Start DocumentDB Local, connect with PyMongo, and run your first queries from Python.',
+ 'Connect to DocumentDB with Docker or Linux packages with PyMongo and run your first queries from Python.',
'getting-started/mongo-shell-quickstart':
- 'Start DocumentDB Local, connect with mongosh, and run your first shell commands.',
+ 'Connect to DocumentDB with Docker or Linux packages with mongosh and insert and read your first document.',
};
function getArticleKey(section: string, file: string): string {
@@ -1682,7 +1746,7 @@ export function getArticleByPath(section: string, slug: string[] = []): {
content: linuxPackagesGuideContent,
frontmatter: {
title: articleTitleOverrides[getArticleKey(section, file)],
- description: 'Install the DocumentDB PostgreSQL extension with Linux packages and find package troubleshooting guidance.',
+ description: articleDescriptionOverrides[getArticleKey(section, file)],
},
navigation,
section,
diff --git a/blogs/_layouts/default.html b/blogs/_layouts/default.html
index 30dbeb6..69aa633 100644
--- a/blogs/_layouts/default.html
+++ b/blogs/_layouts/default.html
@@ -9,6 +9,7 @@
{% endif %}
+
{% assign social_title = page.title | default: site.title %}
{% assign social_description = page.description | default: site.description %}
diff --git a/blogs/_posts/2026-09-10-linux-packages.md b/blogs/_posts/2026-09-10-linux-packages.md
new file mode 100644
index 0000000..63abb33
--- /dev/null
+++ b/blogs/_posts/2026-09-10-linux-packages.md
@@ -0,0 +1,71 @@
+---
+title: "Linux packages for DocumentDB: start simple, keep control"
+description: Install DocumentDB on Linux with apt or dnf and guided setup. Start with the complete stack, use your own local PostgreSQL, or install only the extension.
+date: 2026-09-10
+featured: true
+author: DocumentDB team
+category: documentdb-blog
+tags:
+ - DocumentDB
+ - Linux
+ - PostgreSQL
+ - APT
+ - RPM
+---
+{% assign site_root = site.baseurl | replace: '/blogs', '' %}
+
+Docker remains the fastest way to evaluate DocumentDB on Linux, macOS, or Windows. When you cannot use Docker, or need control over PostgreSQL, services, and configuration on a Linux host, Linux packages give you another option: familiar package managers, guided setup, and a choice about how much of the stack you manage.
+
+DocumentDB is an open-source, MongoDB API compatible document database built on PostgreSQL. The Linux packages bring the PostgreSQL extension, gateway, setup tools, and systemd services together, so you can start with a complete installation instead of assembling individual components.
+
+**Start simple. Keep control.** Use the complete stack for a new instance, or choose an advanced path for PostgreSQL you already manage.
+
+## Start with the complete stack
+
+The complete-stack path creates a new private PostgreSQL instance and a DocumentDB gateway on your Linux host. You do not need PostgreSQL installed beforehand. Package-managed services and persistent database storage give you a host installation you can inspect, stop, and restart with familiar Linux tools.
+
+Installation and setup are separate steps:
+
+1. **Install with apt or dnf.** Follow the [Linux installation guide]({{ site_root }}/docs/getting-started/packages/) to configure the signed DocumentDB and PostgreSQL repositories, meet the distribution prerequisites, and install the complete-stack package for your selected PostgreSQL major. This changes system-wide package sources and installs dependencies.
+2. **Run guided setup.** The guide's `documentdb-setup` command explicitly creates a new private instance, configures the database and gateway, and starts the services. Installing packages alone does not create a working endpoint. Enter the administrator password at the terminal prompt, not in a connection URI or shell history.
+3. **Connect and query.** Install `mongosh` separately if you want to use the shell examples or load the optional sample data. Follow the guide's connection instructions before running your first insert and read.
+
+This is a guided installation, not a one-command path from an unprepared machine to production.
+
+## Try a write, then keep it across a restart
+
+After setup and an authenticated connection in `mongosh`, insert a document and read it back:
+
+```javascript
+use linux_packages_demo
+db.notes.insertOne({ message: "Start simple. Keep control." })
+db.notes.findOne({ message: "Start simple. Keep control." })
+```
+
+The query should return the inserted document, including its `_id`. On a systemd host, follow [Services and paths]({{ site_root }}/docs/linux-packages/#services-and-paths) to restart the complete-stack target for your selected PostgreSQL major. Reconnect, select `linux_packages_demo`, and repeat the query to check that the same data remains. A service restart is not a data reset.
+
+The [operations guide]({{ site_root }}/docs/linux-packages/) keeps service commands, storage paths, troubleshooting, and removal guidance in one place.
+
+## Keep control of PostgreSQL
+
+The complete stack is the starting point, not the only option.
+
+**Use an existing local PostgreSQL instance.** Keep ownership of its service and data while configuring DocumentDB and the gateway alongside it. This requires explicit configuration changes and can require an operator-controlled PostgreSQL restart. Back up first and follow [the existing-instance guide]({{ site_root }}/docs/linux-packages/#adopt-an-existing-postgre-sql-instance). The gateway and PostgreSQL must be on the same host; a remote PostgreSQL backend is not supported.
+
+**Install only the PostgreSQL extension.** Choose this when you want the DocumentDB extension in PostgreSQL without the gateway or package-managed private instance. Extension-only installation does not create a MongoDB-compatible network endpoint. Review the component choices on the install page rather than treating this as a substitute for the complete-stack quickstart.
+
+## Supported platforms and release boundaries
+
+These details describe [v0.117-0](https://github.com/documentdb/documentdb/releases/tag/v0.117-0), the current release as of September 10, 2026. Linux packages are not new to this release.
+
+The shipped package matrix covers Ubuntu 24.04 with APT and RHEL/Rocky Linux 9 with RPM/dnf, on PostgreSQL 17 or 18 and amd64 or arm64. RPM names those architectures x86_64 and aarch64. RHEL requires registration and the documented repository prerequisites. PostgreSQL 18 is the default: `documentdb` selects it, while `documentdb-17` and `documentdb-18` select a specific major.
+
+**These pre-GA packages are for fresh installations. In-place upgrades from earlier releases are not supported.** Use a clean host or a new, empty PostgreSQL instance. Uninstalling packages preserves database files and in-database content; reinstalling does not make an existing database fresh.
+
+The default auto-generated self-signed TLS certificate is a development convenience only. The gateway listens on all interfaces by default, so restrict network access before setup on anything other than a private development machine. Follow [the network and TLS guidance]({{ site_root }}/docs/linux-packages/#before-exposing-it-to-a-network) before exposing the endpoint, and use a trusted certificate instead of treating a certificate-validation bypass as a production setting.
+
+## Choose your installation path
+
+**[Install DocumentDB on Linux]({{ site_root }}/packages/?method=packages)** for the complete, current prerequisites and install/setup commands.
+
+Prefer containers, or evaluating on macOS or Windows? [Use Docker]({{ site_root }}/packages/?method=docker). It remains an option on Linux, macOS, and Windows.
diff --git a/tests/fixtures/getting-started/index.md b/tests/fixtures/getting-started/index.md
new file mode 100644
index 0000000..8823aaa
--- /dev/null
+++ b/tests/fixtures/getting-started/index.md
@@ -0,0 +1,26 @@
+---
+title: Getting Started
+description: Source documentation fixture for onboarding normalization.
+---
+
+# Getting Started
+
+## Architecture Components
+
+Source architecture guidance.
+
+## Common Use Cases
+
+Source use cases remain available alongside the installation instructions.
+
+## Getting Started Options
+
+Read the [pre-built package guide](prebuilt-packages.md).
+
+## Community and Support
+
+Source community and support information remains available.
+
+## Next Steps
+
+Continue with the source documentation.
diff --git a/tests/fixtures/getting-started/navigation.yml b/tests/fixtures/getting-started/navigation.yml
new file mode 100644
index 0000000..8802dce
--- /dev/null
+++ b/tests/fixtures/getting-started/navigation.yml
@@ -0,0 +1,6 @@
+- title: Getting Started
+ link: index.md
+- title: Pre-built Packages
+ link: prebuilt-packages.md
+- title: Node.js Setup
+ link: nodejs-setup.md
diff --git a/tests/installSelection.test.ts b/tests/installSelection.test.ts
new file mode 100644
index 0000000..2e48ec4
--- /dev/null
+++ b/tests/installSelection.test.ts
@@ -0,0 +1,152 @@
+import { describe, expect, it } from "vitest";
+import {
+ defaultInstallSelection,
+ installSelectionQuery,
+ installSelectionUrlQuery,
+ parseInstallSelection,
+ releaseHasPackages,
+ selectInstallTarget,
+} from "../app/lib/installSelection";
+import { FALLBACK_RELEASE, parseReleaseInfo } from "../app/lib/releaseInfo";
+
+describe("install selection links", () => {
+ it("defaults to Docker, with packages preset to the PG18 stack and host-resolved architecture", () => {
+ expect(parseInstallSelection("")).toEqual({ selection: defaultInstallSelection, error: null });
+ });
+
+ it.each(["docker", "packages"])("opens the explicitly linked %s method", (method) => {
+ expect(parseInstallSelection(`?method=${method}`).selection?.method).toBe(method);
+ });
+
+ it.each([
+ "method=packages&family=apt&target=ubuntu24&pg=17&arch=arm64",
+ "method=packages&family=rpm&target=rhel9&pg=18&arch=aarch64",
+ "method=docker&family=rpm&target=rocky9&pg=17&arch=auto",
+ ])("round-trips all choices in %s", (query) => {
+ const result = parseInstallSelection(query);
+ expect(result.error).toBeNull();
+ if (!result.selection) throw new Error("Expected a valid selection");
+ expect(parseInstallSelection(installSelectionQuery(result.selection))).toEqual(result);
+ });
+
+ it.each([
+ "method=other",
+ "family=unknown",
+ "pg=15",
+ "pg=16",
+ "pg=19",
+ "arch=i386",
+ "target=ubuntu22",
+ "target=rocky9",
+ "family=rpm&arch=amd64",
+ "family=rpm&target=rhel8",
+ "method=docker&method=packages",
+ "pg=17&pg=18",
+ "target=__proto__",
+ "target=constructor",
+ "arch=%24%28touch%20anything%29",
+ ])("rejects unsupported or ambiguous choices without a usable command target: %s", (query) => {
+ expect(parseInstallSelection(query)).toEqual({
+ selection: null,
+ error: expect.any(String),
+ recovery: expect.any(Object),
+ });
+ });
+
+ it.each(["pg=16", "method=packages&pg=16", "target=ubuntu22"])(
+ "recovers a broken package link to package settings, not Docker: %s",
+ (query) => {
+ const result = parseInstallSelection(query);
+ expect(result.selection).toBeNull();
+ if (result.error === null) throw new Error("Expected an error");
+ expect(result.recovery).toEqual({ ...defaultInstallSelection, method: "packages" });
+ },
+ );
+
+ it("recovers an unknown method to the Docker default", () => {
+ const result = parseInstallSelection("method=other");
+ if (result.error === null) throw new Error("Expected an error");
+ expect(result.recovery).toEqual(defaultInstallSelection);
+ });
+
+ it("opens Docker even when a link carries stale package choices", () => {
+ expect(parseInstallSelection("method=docker&pg=16&target=ubuntu22")).toEqual({
+ selection: defaultInstallSelection,
+ error: null,
+ });
+ });
+
+ it("treats package choices without a method as a package link", () => {
+ expect(parseInstallSelection("family=rpm&target=rocky9").selection?.method).toBe("packages");
+ });
+
+ it("writes package choices to the URL only for packages", () => {
+ expect(installSelectionUrlQuery(defaultInstallSelection)).toBe("method=docker");
+ const packages = { ...defaultInstallSelection, method: "packages" as const };
+ expect(installSelectionUrlQuery(packages)).toBe(installSelectionQuery(packages));
+ });
+
+ it("allows campaign parameters without treating them as install choices", () => {
+ expect(parseInstallSelection("?utm_source=blog&method=docker").selection).toEqual(defaultInstallSelection);
+ });
+
+ it("preserves major and CPU family when switching distributions", () => {
+ const initial = parseInstallSelection("pg=17&arch=arm64").selection;
+ if (!initial) throw new Error("Expected a valid selection");
+ const rpm = selectInstallTarget(initial, "rhel9");
+ expect(rpm.selection?.packages).toEqual({ family: "rpm", target: "rhel9", arch: "aarch64", pg: "17" });
+ if (!rpm.selection) throw new Error("Expected an RPM selection");
+ expect(selectInstallTarget(rpm.selection, "ubuntu24").selection).toEqual(initial);
+ });
+
+ it("keeps automatic architecture and rejects unknown distributions", () => {
+ expect(selectInstallTarget(defaultInstallSelection, "rocky9").selection?.packages.arch).toBe("auto");
+ expect(selectInstallTarget(defaultInstallSelection, "other").selection).toBeNull();
+ });
+});
+
+describe("published package availability", () => {
+ const assetNames = [
+ ...["documentdb-18", "documentdb-common", "documentdb-postgresql-tools"].flatMap((name) => [
+ `ubuntu24.04-${name}_0.117.0_all.deb`,
+ `${name}-0.117.0-1.noarch.rpm`,
+ ]),
+ ...["amd64", "arm64"].flatMap((arch) => [
+ `ubuntu24.04-documentdb-gateway_0.117.0_${arch}.deb`,
+ `ubuntu24.04-postgresql-18-documentdb_0.117-0_${arch}.deb`,
+ ]),
+ ...["x86_64", "aarch64"].flatMap((arch) => [
+ `documentdb-gateway-0.117.0-1.el9.${arch}.rpm`,
+ `rhel9-postgresql18-documentdb-0.117.0-1.el9.${arch}.rpm`,
+ ]),
+ ];
+ const release = { ...FALLBACK_RELEASE, assetNames };
+
+ it("requires the full stack, including both architectures for automatic selection", () => {
+ expect(releaseHasPackages(release, defaultInstallSelection.packages)).toBe(true);
+ expect(releaseHasPackages(release, { family: "rpm", target: "rhel9", arch: "auto", pg: "18" })).toBe(true);
+ expect(releaseHasPackages(FALLBACK_RELEASE, defaultInstallSelection.packages)).toBe(false);
+ expect(releaseHasPackages(release, { family: "apt", target: "ubuntu24", arch: "amd64", pg: "17" })).toBe(false);
+ });
+
+ it.each(assetNames)("does not advertise a complete automatic install without %s", (missing) => {
+ const partial = { ...release, assetNames: assetNames.filter((name) => name !== missing) };
+ const selection = missing.endsWith(".deb")
+ ? defaultInstallSelection.packages
+ : { family: "rpm" as const, target: "rocky9" as const, arch: "auto" as const, pg: "18" as const };
+ expect(releaseHasPackages(partial, selection)).toBe(false);
+ });
+
+ it("allows a specific shipped architecture when the other one is missing", () => {
+ const partial = { ...release, assetNames: assetNames.filter((name) => !name.includes("_arm64.deb")) };
+ expect(releaseHasPackages(partial, { family: "apt", target: "ubuntu24", arch: "amd64", pg: "18" })).toBe(true);
+ expect(releaseHasPackages(partial, defaultInstallSelection.packages)).toBe(false);
+ });
+
+ it.each([null, {}, { tag_name: "v0.117-0", assets: [] }, { tag_name: "../other", assets: [] }])(
+ "surfaces malformed or incomplete metadata instead of inventing current versions",
+ (payload) => {
+ expect(() => parseReleaseInfo(payload)).toThrow();
+ },
+ );
+});
diff --git a/tests/packageArticles.test.ts b/tests/packageArticles.test.ts
index 63b5482..c19596a 100644
--- a/tests/packageArticles.test.ts
+++ b/tests/packageArticles.test.ts
@@ -1,9 +1,18 @@
-import { describe, expect, it } from 'vitest';
+import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
+import fs from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+import { kebabCase } from 'change-case';
import {
getArticleByPath,
linuxPackagesGuideContent,
linuxPackagesOperationsContent,
} from '../app/services/articleService';
+import {
+ buildAptInstallCommand,
+ buildRpmInstallCommand,
+ buildSetupCommand,
+} from '../app/lib/packageInstall';
function getCodeBlocks(content: string, language: string): string[] {
const pattern = new RegExp('```' + language + '\\n([\\s\\S]*?)\\n```', 'g');
@@ -11,6 +20,179 @@ function getCodeBlocks(content: string, language: string): string[] {
}
describe('Linux package articles', () => {
+ beforeEach(() => {
+ const fixturePaths = new Map(
+ ['index.md', 'navigation.yml'].map((file) => [
+ path.join(process.cwd(), 'articles', 'getting-started', file),
+ fileURLToPath(new URL(`./fixtures/getting-started/${file}`, import.meta.url)),
+ ]),
+ );
+ const existsSync = fs.existsSync;
+ const readFileSync = fs.readFileSync;
+
+ vi.spyOn(fs, 'existsSync').mockImplementation((file) =>
+ existsSync(fixturePaths.get(file.toString()) ?? file),
+ );
+ vi.spyOn(fs, 'readFileSync').mockImplementation((file, options) =>
+ readFileSync(fixturePaths.get(file.toString()) ?? file, options),
+ );
+ });
+
+ afterEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it('uses the shared Linux package install and fresh-instance setup commands', () => {
+ const blocks = getCodeBlocks(linuxPackagesGuideContent, 'bash');
+
+ expect(blocks).toContain(buildAptInstallCommand('ubuntu24', 'auto', '18'));
+ expect(blocks).toContain(buildRpmInstallCommand('rocky9', 'auto', '18'));
+ expect(blocks).toContain(buildRpmInstallCommand('rhel9', 'auto', '18'));
+ expect(blocks).toContain(buildSetupCommand('18'));
+ expect(linuxPackagesGuideContent).toContain('amd64 or arm64');
+ expect(linuxPackagesGuideContent.indexOf('fresh installation only')).toBeLessThan(
+ linuxPackagesGuideContent.indexOf('```bash'),
+ );
+ expect(linuxPackagesGuideContent).toContain('not in-place package upgrades');
+ expect(linuxPackagesGuideContent).toContain(
+ 'Removing packages preserves database files',
+ );
+ expect(linuxPackagesGuideContent).toContain('**all interfaces**');
+ expect(linuxPackagesGuideContent).toContain('Firewall port `10260`');
+ expect(linuxPackagesGuideContent).toContain('**local development only**');
+ expect(linuxPackagesGuideContent).toContain('> use quickstart');
+ expect(linuxPackagesGuideContent).toContain('db.orders.insertOne(');
+ expect(linuxPackagesGuideContent).toContain('db.orders.find(');
+ expect(linuxPackagesGuideContent).toContain(
+ 'mongosh localhost:10260 -u admin -p --authenticationMechanism',
+ );
+ expect(getArticleByPath('getting-started', ['packages'])?.frontmatter.description)
+ .toContain('Ubuntu APT or EL9 RPM/dnf packages');
+ });
+
+ it('aligns the Getting Started article and renderer with goal-based installation choices', async () => {
+ const article = getArticleByPath('getting-started', []);
+ if (!article) {
+ throw new Error('Missing Getting Started landing article');
+ }
+
+ const startHere = article.content.split('## Start here')[1]?.split('## Verify your setup')[0];
+ expect(startHere).toContain('/packages?method=packages');
+ expect(startHere).toContain('/packages?method=docker');
+ expect(startHere?.indexOf('/packages?method=docker')).toBeLessThan(
+ startHere?.indexOf('/packages?method=packages') ?? -1,
+ );
+ expect(startHere).toContain('recommended for evaluation and development');
+ expect(startHere).toContain('install packages, then run the setup wizard');
+ expect(startHere).toContain('no second server installation is needed');
+ expect(article.content).toContain('db.orders.insertOne(');
+ expect(article.content).toContain('db.orders.find(');
+ expect(article.content).toContain('acknowledged: true');
+ expect(article.content).toContain('Install [mongosh]');
+ expect(article.content).toContain('## Architecture Components');
+ expect(article.content).toContain('## Common Use Cases');
+ expect(article.content).toContain('## Community and Support');
+ const packageIndex = article.navigation.findIndex((item) =>
+ item.link === '/docs/getting-started/packages',
+ );
+ const dockerIndex = article.navigation.findIndex((item) =>
+ item.link === '/docs/getting-started/docker',
+ );
+ expect(dockerIndex).toBeGreaterThanOrEqual(0);
+ expect(packageIndex).toBeGreaterThan(dockerIndex);
+
+ const { readFile } = await import('node:fs/promises');
+ const { fileURLToPath } = await import('node:url');
+ const source = await readFile(
+ fileURLToPath(new URL('../app/docs/[section]/[[...slug]]/page.tsx', import.meta.url)),
+ 'utf8',
+ );
+
+ expect(source).toContain('href="/packages?method=packages"');
+ // The Docker card has one destination; the install page would only repeat its command.
+ expect(source).not.toContain('href="/packages?method=docker"');
+ expect(source.indexOf('href="/docs/getting-started/docker"')).toBeLessThan(
+ source.indexOf('href="/packages?method=packages"'),
+ );
+ expect(source).toContain('-p 127.0.0.1:10260:10260');
+ expect(source).not.toContain('-p 10260:10260');
+ expect(source).toContain("--username ''");
+ expect(source).toContain("--password ''");
+ expect(source).toContain('Pre-GA, fresh installation only');
+ });
+
+ it('offers both server methods before client-specific setup or optional Docker commands', () => {
+ for (const slug of ['nodejs-setup', 'python-setup', 'mongo-shell-quickstart']) {
+ const article = getArticleByPath('getting-started', [slug]);
+ if (!article) {
+ throw new Error(`Missing client quick start ${slug}`);
+ }
+ const content = article.content;
+ const prerequisite = content.split('## Have a running DocumentDB instance?')[1]
+ ?.split('## Prerequisites')[0];
+
+ expect(prerequisite, slug).toContain('/packages?method=packages');
+ expect(prerequisite, slug).toContain('/packages?method=docker');
+ expect(prerequisite, slug).toContain('localhost:10260');
+ expect(prerequisite, slug).toContain('username `admin`');
+ expect(prerequisite, slug).toContain('**local development only**');
+ expect(prerequisite, slug).toContain('firewall port `10260`');
+ expect(content, slug).toContain('## Optional: start a Docker instance');
+ expect(content, slug).toContain('Skip this if you installed Linux packages');
+ expect(content, slug).toContain('Wait for the readiness banner');
+ expect(content, slug).not.toContain('For the fastest local setup');
+ expect(content.indexOf('/packages?method=packages'), slug).toBeLessThan(
+ content.indexOf('docker run'),
+ );
+ }
+ });
+
+ it('keeps first writes independent of optional sample data for both installation methods', () => {
+ for (const slug of ['python-setup', 'mongo-shell-quickstart']) {
+ const content = getArticleByPath('getting-started', [slug])?.content;
+ expect(content, slug).toContain('not required for your first insert and read');
+ expect(content, slug).toContain('`--load-sample-data` during setup');
+ expect(content, slug).toContain('separately requires [mongosh]');
+ expect(content, slug).toContain('`--init-data true`');
+ }
+ const docker = getArticleByPath('getting-started', ['docker'])?.content;
+ expect(docker).toContain('db.orders.insertOne(');
+ expect(docker).toContain('db.orders.find(');
+ });
+
+ it('documents trusted certificates without requiring Docker for Linux package clients', () => {
+ for (const slug of ['nodejs-setup', 'python-setup', 'mongo-shell-quickstart']) {
+ const content = getArticleByPath('getting-started', [slug])?.content;
+ expect(content, slug).toContain('For Linux packages, follow [certificate configuration]');
+ expect(content, slug).toContain('/docs/linux-packages#before-exposing-it-to-a-network');
+ expect(content, slug).toContain('For Docker, copy the local certificate with:');
+ expect(content, slug).toContain('tlsCAFile');
+ }
+ });
+
+ it('links to rendered section anchors in the advanced Linux packages guide', () => {
+ const anchors = Array.from(
+ linuxPackagesOperationsContent.matchAll(/^## (.+)$/gm),
+ (match) => kebabCase(match[1]),
+ );
+ for (const slug of [
+ [], ['packages'], ['nodejs-setup'], ['python-setup'], ['mongo-shell-quickstart'],
+ ]) {
+ const article = getArticleByPath('getting-started', slug);
+ if (!article) {
+ throw new Error(`Missing Getting Started article ${slug.join('/')}`);
+ }
+ const links = Array.from(
+ article.content.matchAll(/\]\(\/docs\/linux-packages#([^)]+)\)/g),
+ (match) => match[1],
+ );
+ expect(links.length).toBeGreaterThan(0);
+ for (const anchor of links) {
+ expect(anchors).toContain(anchor);
+ }
+ }
+ });
+
it('keeps advanced setup details out of the quick start', () => {
expect(linuxPackagesGuideContent).toContain(
'/docs/linux-packages#unattended-setup',
@@ -35,6 +217,33 @@ describe('Linux package articles', () => {
expect(linuxPackagesOperationsContent).toContain(
'DOCUMENTDB_TOAST_COMPRESSION=default',
);
+ expect(linuxPackagesOperationsContent).toContain(
+ '**locally on the gateway host**',
+ );
+ expect(linuxPackagesOperationsContent).toContain(
+ 'remote PostgreSQL adoption is not supported',
+ );
+ expect(linuxPackagesOperationsContent).toContain(
+ 'administrator access to change PostgreSQL configuration and restart its service',
+ );
+ });
+
+ it('keeps extension-only guidance advanced and systemd names per major', () => {
+ expect(linuxPackagesGuideContent).toContain(
+ '/docs/linux-packages#install-the-postgre-sql-extension-only',
+ );
+ expect(linuxPackagesOperationsContent).toContain(
+ '## Install the PostgreSQL extension only',
+ );
+ expect(linuxPackagesOperationsContent).toContain(
+ 'does **not** create a MongoDB-compatible network endpoint',
+ );
+ expect(linuxPackagesOperationsContent).toContain(
+ 'sudo systemctl restart documentdb-local@18.target',
+ );
+ expect(linuxPackagesOperationsContent).not.toContain(
+ 'sudo systemctl restart documentdb-local.target',
+ );
});
it('distinguishes scoped systemd restore from no-systemd cleanup', () => {
@@ -291,6 +500,17 @@ describe('Linux package articles', () => {
(block) => block.includes('docker run'),
);
+ for (const content of [nodeGuide.content, pythonGuide.content]) {
+ const block = getCodeBlocks(content, 'bash').find(
+ (value) => value.includes('export DOCUMENTDB_USERNAME='),
+ );
+ expect(block).toContain("export DOCUMENTDB_USERNAME=''");
+ expect(block).toContain("export DOCUMENTDB_PASSWORD=''");
+ expect(content.indexOf('## Set your client credentials')).toBeLessThan(
+ content.indexOf('## Optional: start a Docker instance'),
+ );
+ }
+
for (const block of [nodeDockerBlock, pythonDockerBlock]) {
expect(block).toContain("export DOCUMENTDB_USERNAME=''");
expect(block).toContain("export DOCUMENTDB_PASSWORD=''");
From 936ec456d436c9fc1ff24157354124dd9890abb9 Mon Sep 17 00:00:00 2001
From: Guanzhou Song
Date: Wed, 23 Sep 2026 18:11:02 -0400
Subject: [PATCH 2/4] Keep install choices across methods and stop hiding
commands on metadata errors
---
app/docs/[section]/[[...slug]]/page.tsx | 2 +-
app/lib/installSelection.ts | 8 ++-
app/packages/page.tsx | 69 +++++++++++++++--------
blogs/_posts/2026-09-10-linux-packages.md | 6 +-
tests/installSelection.test.ts | 10 +++-
5 files changed, 63 insertions(+), 32 deletions(-)
diff --git a/app/docs/[section]/[[...slug]]/page.tsx b/app/docs/[section]/[[...slug]]/page.tsx
index d0e0107..518c31b 100644
--- a/app/docs/[section]/[[...slug]]/page.tsx
+++ b/app/docs/[section]/[[...slug]]/page.tsx
@@ -306,7 +306,7 @@ export default async function ArticlePage({ params }: PageProps) {
Linux packages installation
diff --git a/app/lib/installSelection.ts b/app/lib/installSelection.ts
index 0dbd3b4..21a75ee 100644
--- a/app/lib/installSelection.ts
+++ b/app/lib/installSelection.ts
@@ -99,9 +99,13 @@ export function installSelectionQuery(selection: InstallSelection): string {
return new URLSearchParams({ method: selection.method, family, target, pg, arch }).toString();
}
-// The shareable URL: package choices only matter, and are only written, for packages.
+// Docker links stay short, but keep non-default package choices so switching back restores them.
export function installSelectionUrlQuery(selection: InstallSelection): string {
- return selection.method === "docker" ? "method=docker" : installSelectionQuery(selection);
+ const { family, target, pg, arch } = selection.packages;
+ const defaults = defaultInstallSelection.packages;
+ const packagesChanged = family !== defaults.family || target !== defaults.target
+ || pg !== defaults.pg || arch !== defaults.arch;
+ return selection.method === "docker" && !packagesChanged ? "method=docker" : installSelectionQuery(selection);
}
export function selectInstallTarget(selection: InstallSelection, target: string): SelectionResult {
diff --git a/app/packages/page.tsx b/app/packages/page.tsx
index 6840d55..8f43e11 100644
--- a/app/packages/page.tsx
+++ b/app/packages/page.tsx
@@ -33,8 +33,11 @@ const dockerCommand = `docker run -dt --name documentdb \\
--username '
' \\
--password ''`;
-const firstQuery = `db.starter.insertOne({ message: "Hello, DocumentDB!" })
-db.starter.findOne({ message: "Hello, DocumentDB!" })`;
+const dockerReadyCommand = `until docker logs documentdb 2>&1 | grep -q "=== DocumentDB is ready ==="; do sleep 2; done`;
+
+const firstQuery = `use quickstart
+db.orders.insertOne({ item: "widget", qty: 5 })
+db.orders.find({ item: "widget" })`;
const nextGuides = [
{ title: "Python", description: "Connect with PyMongo.", href: "/docs/getting-started/python-setup" },
@@ -79,8 +82,9 @@ export default function PackagesPage() {
const { method, packages } = selection;
const { family, target, pg, arch } = packages;
const selectionReady = state !== null && state.error === null;
- const packagesAvailable = releaseStatus === "live" && releaseHasPackages(release, packages);
- const canInstall = selectionReady && packagesAvailable;
+ // The commands install from the package repository, so only a confirmed gap in the release withholds them.
+ const packagesMissing = releaseStatus === "live" && !releaseHasPackages(release, packages);
+ const canInstall = selectionReady && !packagesMissing;
const targetLabel = packages.family === "apt" ? aptTargetLabels[packages.target] : rpmTargetLabels[packages.target];
const selectedPackageNames = `documentdb-${pg}`;
const packagingGuideUrl = `https://github.com/documentdb/documentdb/blob/${release.tagName}/packaging/README.md`;
@@ -88,8 +92,9 @@ export default function PackagesPage() {
const installCommand = packages.family === "apt"
? buildAptInstallCommand(packages.target, packages.arch, packages.pg)
: buildRpmInstallCommand(packages.target, packages.arch, packages.pg);
- const connectionCommand = `mongosh 'mongodb://127.0.0.1:10260/mydb?authSource=admin&tls=true&tlsAllowInvalidCertificates=true' \\
- --username ${method === "packages" ? "admin" : "''"} --password`;
+ // Same form as the getting-started guides.
+ const connectionCommand = `mongosh localhost:10260 -u ${method === "packages" ? "admin" : "''"} -p \\
+ --authenticationMechanism SCRAM-SHA-256 --tls --tlsAllowInvalidCertificates`;
function choose(result: SelectionResult) {
setState(result);
@@ -99,7 +104,7 @@ export default function PackagesPage() {
for (const [key, value] of new URLSearchParams(installSelectionUrlQuery(result.selection))) {
url.searchParams.set(key, value);
}
- window.history.pushState(null, "", url);
+ window.history.replaceState(null, "", url);
}
function changeChoice(key: "method" | "pg" | "arch", value: string) {
@@ -120,7 +125,10 @@ export default function PackagesPage() {
Use Docker to evaluate and develop on Linux, macOS, or Windows. On a supported Linux
host, Linux packages give you control over PostgreSQL, services, and configuration.
- Looking for individual package downloads?
+
+ Download release assets
+ {" · "}Package details
+
@@ -131,10 +139,10 @@ export default function PackagesPage() {
changeChoice("method", item.value)}
className={`rounded-xl border p-5 text-left transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400 ${
- method === item.value ? "border-blue-400 bg-blue-500/15" : "border-neutral-700 bg-neutral-800/60 hover:bg-neutral-800"
+ state !== null && method === item.value ? "border-blue-400 bg-blue-500/15" : "border-neutral-700 bg-neutral-800/60 hover:bg-neutral-800"
}`}
>
{item.title}
@@ -165,10 +173,13 @@ export default function PackagesPage() {
)}
- {method === "packages" ? (
+ {/* The static page can't see the query string, so show no flow until it is read. */}
+ {state === null ? (
+ Loading installation steps...
+ ) : method === "packages" ? (
<>
- One complete stack. No package decisions.
+ Choose your Linux host
The selected {selectedPackageNames} package brings PostgreSQL, the extension,
gateway, setup tools, and services together. The number {pg} is the PostgreSQL major,
@@ -216,28 +227,28 @@ export default function PackagesPage() {
-
+
{releaseStatus === "loading" ? (
-
Checking the published package release...
+
Checking the published package release...
) : releaseStatus === "fallback" ? (
Cannot confirm the current repository release. {releaseError}
- Reference release: {release.tagName}, not confirmed current. Installation commands are
- withheld until availability can be confirmed.{" "}
+ The commands below install the latest packages from the repository. Last known
+ release: {release.tagName}.{" "}
Browse release assets {" "}
or window.location.reload()} className={linkClass}>retry the lookup .
) : (
-
+
Published repository release:{" "}
{release.tagName}
{" · "}{targetLabel}{" · "}{arch === "auto" ? "AMD64 / ARM64" : arch}
)}
- {selectionReady && releaseStatus === "live" && !packagesAvailable && (
+ {selectionReady && packagesMissing && (
The complete package set for this selection is not present in the published release.
Choose another target or a specific available architecture, or{" "}
@@ -253,7 +264,7 @@ export default function PackagesPage() {
stack. Review the command before running it. Installation does not start a usable DocumentDB endpoint.
{canInstall ?
: (
-
Commands will appear after your selection and the published package set are confirmed.
+
No command is shown for this selection.
)}
{family === "apt" ? (
@@ -337,7 +348,15 @@ export default function PackagesPage() {
Install and start Docker first. Replace both credential placeholders before running the
command. This local example exposes port 10260 only on your machine's loopback interface.
- {selectionReady &&
}
+ {selectionReady && (
+ <>
+
+
+ The container is up before DocumentDB accepts connections. Wait for the readiness banner:
+
+
+ >
+ )}
The container initializes the database; do not run the Linux package setup wizard inside it.
For persistent volumes and a versioned image, follow the{" "}
@@ -348,7 +367,7 @@ export default function PackagesPage() {
>
)}
- {!(method === "docker" && dockerSetup === "guided") && (
+ {state !== null && !(method === "docker" && dockerSetup === "guided") && (
{method === "packages" ? "3" : "2"}. Connect and run your first query
@@ -356,7 +375,7 @@ export default function PackagesPage() {
mongosh {" "}
separately, then connect from the same host as DocumentDB.{" "}
{method === "packages" ? "Use the admin password you chose during setup." : "Use the username and password you chose for Docker."}{" "}
- The shell prompts for the password; it is not included in the connection URI.
+ The shell prompts for the password, so it stays out of your shell history.
{selectionReady && (method === "docker" || canInstall) && (
<>
@@ -366,8 +385,8 @@ export default function PackagesPage() {
>
)}
- Expect an acknowledged insert and a document containing "Hello, DocumentDB!".
- The example uses the mydb database. The self-signed certificate bypass is
+ Expect an acknowledged insert and the widget document back.
+ The example uses the quickstart database. The self-signed certificate bypass is
for local development only; use trusted certificates and remove the bypass for other deployments.
@@ -381,7 +400,7 @@ export default function PackagesPage() {
)}
- {method === "packages" && (
+ {state !== null && method === "packages" && (
Keep control after the first query
diff --git a/blogs/_posts/2026-09-10-linux-packages.md b/blogs/_posts/2026-09-10-linux-packages.md
index 63abb33..455b19a 100644
--- a/blogs/_posts/2026-09-10-linux-packages.md
+++ b/blogs/_posts/2026-09-10-linux-packages.md
@@ -37,12 +37,12 @@ This is a guided installation, not a one-command path from an unprepared machine
After setup and an authenticated connection in `mongosh`, insert a document and read it back:
```javascript
-use linux_packages_demo
+use quickstart
db.notes.insertOne({ message: "Start simple. Keep control." })
db.notes.findOne({ message: "Start simple. Keep control." })
```
-The query should return the inserted document, including its `_id`. On a systemd host, follow [Services and paths]({{ site_root }}/docs/linux-packages/#services-and-paths) to restart the complete-stack target for your selected PostgreSQL major. Reconnect, select `linux_packages_demo`, and repeat the query to check that the same data remains. A service restart is not a data reset.
+The query should return the inserted document, including its `_id`. On a systemd host, follow [Services and paths]({{ site_root }}/docs/linux-packages/#services-and-paths) to restart the complete-stack target for your selected PostgreSQL major. Reconnect, select `quickstart`, and repeat the query to check that the same data remains. A service restart is not a data reset.
The [operations guide]({{ site_root }}/docs/linux-packages/) keeps service commands, storage paths, troubleshooting, and removal guidance in one place.
@@ -56,7 +56,7 @@ The complete stack is the starting point, not the only option.
## Supported platforms and release boundaries
-These details describe [v0.117-0](https://github.com/documentdb/documentdb/releases/tag/v0.117-0), the current release as of September 10, 2026. Linux packages are not new to this release.
+These details describe [v0.117-0](https://github.com/documentdb/documentdb/releases/tag/v0.117-0), the current release as of September 10, 2026.
The shipped package matrix covers Ubuntu 24.04 with APT and RHEL/Rocky Linux 9 with RPM/dnf, on PostgreSQL 17 or 18 and amd64 or arm64. RPM names those architectures x86_64 and aarch64. RHEL requires registration and the documented repository prerequisites. PostgreSQL 18 is the default: `documentdb` selects it, while `documentdb-17` and `documentdb-18` select a specific major.
diff --git a/tests/installSelection.test.ts b/tests/installSelection.test.ts
index 2e48ec4..50326a1 100644
--- a/tests/installSelection.test.ts
+++ b/tests/installSelection.test.ts
@@ -80,12 +80,20 @@ describe("install selection links", () => {
expect(parseInstallSelection("family=rpm&target=rocky9").selection?.method).toBe("packages");
});
- it("writes package choices to the URL only for packages", () => {
+ it("keeps Docker links short unless package choices were changed", () => {
expect(installSelectionUrlQuery(defaultInstallSelection)).toBe("method=docker");
const packages = { ...defaultInstallSelection, method: "packages" as const };
expect(installSelectionUrlQuery(packages)).toBe(installSelectionQuery(packages));
});
+ it("restores package choices after switching to Docker and back", () => {
+ const chosen = parseInstallSelection("method=packages&family=rpm&target=rhel9&pg=17&arch=aarch64").selection!;
+ const docker = parseInstallSelection(installSelectionUrlQuery({ ...chosen, method: "docker" })).selection!;
+ expect(docker.method).toBe("docker");
+ const back = parseInstallSelection(installSelectionUrlQuery({ ...docker, method: "packages" })).selection;
+ expect(back).toEqual(chosen);
+ });
+
it("allows campaign parameters without treating them as install choices", () => {
expect(parseInstallSelection("?utm_source=blog&method=docker").selection).toEqual(defaultInstallSelection);
});
From 3bdc2ea3c7b991fe32bc3374cdd91791e8d39867 Mon Sep 17 00:00:00 2001
From: Guanzhou Song
Date: Mon, 28 Sep 2026 10:16:04 -0400
Subject: [PATCH 3/4] Simplify the install page and drop mongo wording
The install page read like an operations manual. It now shows one command per step and sends detail to the guides. Also corrects statements that didn't match v0.117-0 packaging.
---
app/docs/[section]/[[...slug]]/page.tsx | 16 +-
app/packages/page.tsx | 475 ++++++++--------------
app/services/articleService.ts | 10 +-
blogs/_posts/2026-09-10-linux-packages.md | 8 +-
tests/packageArticles.test.ts | 6 +-
5 files changed, 184 insertions(+), 331 deletions(-)
diff --git a/app/docs/[section]/[[...slug]]/page.tsx b/app/docs/[section]/[[...slug]]/page.tsx
index 518c31b..1662ba0 100644
--- a/app/docs/[section]/[[...slug]]/page.tsx
+++ b/app/docs/[section]/[[...slug]]/page.tsx
@@ -331,27 +331,19 @@ export default async function ArticlePage({ params }: PageProps) {
Insert and read your first document
- Install mongosh separately for the shell walkthrough below, or
- use your preferred language or editor. Each guide connects to
- the instance you already created and verifies an insert and read.
+ Pick the client you prefer. Each guide connects to the
+ instance you already created and verifies an insert and read.
Sample data is optional.
- Mongo Shell Quick Start
+ Visual Studio Code Quick Start
Or go directly to{" "}
-
- Visual Studio Code Quick Start
-
- ,{" "}
' \\
--password ''`;
-const dockerReadyCommand = `until docker logs documentdb 2>&1 | grep -q "=== DocumentDB is ready ==="; do sleep 2; done`;
-
-const firstQuery = `use quickstart
-db.orders.insertOne({ item: "widget", qty: 5 })
-db.orders.find({ item: "widget" })`;
-
const nextGuides = [
- { title: "Python", description: "Connect with PyMongo.", href: "/docs/getting-started/python-setup" },
- { title: "Node.js", description: "Use the MongoDB Node.js driver.", href: "/docs/getting-started/nodejs-setup" },
- { title: "Visual Studio Code", description: "Explore your data in the editor.", href: "/docs/getting-started/vscode-quickstart" },
+ { title: "VS Code", href: "/docs/getting-started/vscode-quickstart" },
+ { title: "Python", href: "/docs/getting-started/python-setup" },
+ { title: "Node.js", href: "/docs/getting-started/nodejs-setup" },
] as const;
const packageRoles = [
{ name: "documentdb-N", role: "The complete stack for PostgreSQL major N. Owns that instance's service lifecycle." },
{ name: "postgresql-N-documentdb", role: "PostgreSQL extension files. RPM uses postgresqlN-documentdb." },
- { name: "documentdb-gateway", role: "The MongoDB-compatible wire-protocol runtime." },
+ { name: "documentdb-gateway", role: "The wire-protocol gateway your apps and tools connect to." },
{ name: "documentdb-postgresql-tools", role: "Tools for configuration, gateway registration, and user administration." },
{ name: "documentdb-common", role: "The shared setup wizard, service templates, helpers, and optional sample data." },
];
@@ -57,6 +51,8 @@ const linkClass = "text-blue-300 underline decoration-blue-300/40 underline-offs
// Touch screens get 16px selects in any orientation, since iOS zooms into smaller form fields
const selectClass = "mt-2 w-full rounded-lg border border-neutral-600 bg-neutral-900 px-3 py-3 text-sm pointer-coarse:text-base text-white focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400";
const panelClass = "rounded-xl border border-neutral-700 bg-neutral-800/60 p-4 sm:p-6";
+const stepClass = "mt-8 text-xl font-bold text-white";
+const stepTextClass = "mb-3 mt-2 text-sm leading-6 text-gray-300";
const vscodeGuideUrl = "/docs/getting-started/vscode-quickstart";
// Same two Docker workflows, with the same names, as the homepage quick start.
@@ -92,9 +88,6 @@ export default function PackagesPage() {
const installCommand = packages.family === "apt"
? buildAptInstallCommand(packages.target, packages.arch, packages.pg)
: buildRpmInstallCommand(packages.target, packages.arch, packages.pg);
- // Same form as the getting-started guides.
- const connectionCommand = `mongosh localhost:10260 -u ${method === "packages" ? "admin" : "''"} -p \\
- --authenticationMechanism SCRAM-SHA-256 --tls --tlsAllowInvalidCertificates`;
function choose(result: SelectionResult) {
setState(result);
@@ -113,41 +106,49 @@ export default function PackagesPage() {
choose(parseInstallSelection(params.toString()));
}
+ const firstQuerySteps = (
+ <>
+
+ Pick a client. Each guide connects to the instance you just started
+ {method === "packages" ? " as admin" : ""}, inserts a document, and reads it back.
+
+
+ {nextGuides.map((guide) => (
+
+ {guide.title}
+
+ ))}
+
+ >
+ );
+
return (