DocumentDB Local navigation

DocumentDB Local

DocumentDB Local provides a lightweight, containerized environment for developing and testing applications locally, including prototyping and integration testing.

The examples below use the PostgreSQL 17 image from release 0.117.0. Other PostgreSQL major versions and image tags are listed in the 0.117 release.

Prerequisites

Installation

Get the Docker container image using docker pull.

docker pull ghcr.io/documentdb/documentdb/documentdb-local:pg17-0.117.0

Running

To run the container, use docker run. Afterwards, use docker ps to validate that the container is running.

read -r -p 'DocumentDB username: ' DOCUMENTDB_USERNAME
read -r -s -p 'DocumentDB password: ' DOCUMENTDB_PASSWORD
printf '\n'
export DOCUMENTDB_USERNAME DOCUMENTDB_PASSWORD

docker run -dt -p 127.0.0.1:10260:10260 --name docdb \
  ghcr.io/documentdb/documentdb/documentdb-local:pg17-0.117.0 \
  --username "${DOCUMENTDB_USERNAME:?DocumentDB username cannot be empty}" \
  --password "${DOCUMENTDB_PASSWORD:?DocumentDB password cannot be empty}"


docker ps
CONTAINER ID   IMAGE                                                                             COMMAND                  CREATED         STATUS         PORTS                              NAMES
5aff734a3591   ghcr.io/documentdb/documentdb/documentdb-local:pg17-0.117.0                        "/bin/bash -c '/home…"   5 seconds ago   Up 4 seconds   127.0.0.1:10260->10260/tcp       docdb

The prompts export the credentials for the later client examples, and the guards prevent an empty value from falling through to the image's public defaults. If you open a new shell, set both variables again. The loopback binding makes the gateway reachable only from this host. To allow remote clients, change it to -p 10260:10260 only after restricting the port with a firewall and configuring a certificate that remote clients can validate.

This container writes its database to /data, which the image declares as a Docker volume. The command above mounts nothing there, so each docker run gets a fresh anonymous volume: the data does not survive re-creating the container, and the old volume is left behind on the host until you prune it. Mount a named volume - -v documentdb-data:/data - to persist it. See --data-path in the table below.

Wait for the container to be ready

docker ps reports the container as Up well before DocumentDB can accept connections - PostgreSQL has to initialize, the extensions have to be set up, and the admin user has to be created first. Connecting too early fails with MongoServerSelectionError or ECONNREFUSED.

The entrypoint prints a ready banner after gateway startup and any requested data initialization finish. Wait for it before connecting:

until docker logs docdb 2>&1 | grep -q "=== DocumentDB is ready ==="; do sleep 2; done

First start typically takes a few tens of seconds. If the command has not returned after a couple of minutes, the container most likely exited during startup - interrupt it and check docker ps -a and docker logs docdb for the error.

Use docker logs docdb rather than docker logs -f docdb to check readiness. The container streams the PostgreSQL, gateway, and entrypoint logs to stdout for its whole lifetime, so -f never returns.

Connect with mongosh

The DocumentDB gateway endpoint is available on port 10260 by default. To access this with mongosh, run:

mongosh localhost:10260 \
  -u "${DOCUMENTDB_USERNAME:?Set DOCUMENTDB_USERNAME first}" \
  -p "${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD first}" \
  --authenticationMechanism SCRAM-SHA-256 \
  --tls --tlsAllowInvalidCertificates
Current Mongosh Log ID:	690cdcb84e2e610f0f48e609
Connecting to:		mongodb://<credentials>@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true&directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.5.1
Using MongoDB:		7.0.0
Using Mongosh:		2.5.1
mongosh 2.5.9 is available for download: https://www.mongodb.com/try/download/shell

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

[direct: mongos] test>

Docker commands

The following table summarizes the available Docker commands for configuring the emulator. This table details the corresponding arguments, environment variables, allowed values, default settings, and descriptions of each command.

RequirementArgEnvAllowed valuesDefaultDescription
Print the settings to stdout from the container--help, -hN/AN/AN/ADisplay information on available configuration
Specify the username for DocumentDB.--username [value]Overrides USERNAME environment variableSTRINGdefault_userUsername for DocumentDB. It may not be an internal DocumentDB role name, and it may not begin with documentdb, citus, pg, or internal_role (case-insensitive). The container rejects a reserved name and exits before starting anything.
Specify the password for DocumentDB.--password [value]Overrides PASSWORD environment variableSTRINGAdmin100Password for DocumentDB. Always set this explicitly. The built-in default is well known, and anyone who can reach the published port can authenticate with it.
The port of the DocumentDB endpoint.--documentdb-port [value]Overrides DOCUMENTDB_PORT environment variableINT10260The port needs to be published. For local use, bind only to loopback - for example, -p 127.0.0.1:10260:10260. To use host port 27017 without changing the gateway port, publish -p 127.0.0.1:27017:10260; add --documentdb-port 27017 only when changing the container-side port too.
Specify a directory for data.--data-path [value]Overrides DATA_PATH environment variable.STRING/dataData is not persisted unless you mount a volume at this path - for example, -v documentdb-data:/data. To use a different directory, set the mount and the flag together, keeping in mind that they go on opposite sides of the image name: -v / --mount is a docker run option and comes before it, --data-path is a container argument and comes after it. See the example below the table.
Specify the owner.--owner [value]Overrides OWNER environment variable.STRINGdocumentdbThe PostgreSQL role used to create the admin user. The cluster this image initializes has a single superuser role, documentdb, so leave this at the default: any other value fails with role "<value>" does not exist after PostgreSQL has already initialized, and the container exits.
Specify whether to start the PostgreSQL server.--start-pg [value]Overrides START_POSTGRESQL environment variabletrue, falsetrueSet this to false only when you are pointing the gateway at a PostgreSQL server you run yourself; the container then expects one to be reachable on --pg-port.
Specify whether to create a user.--create-user [value]Overrides CREATE_USER environment variabletrue, falsetrueWith false the container starts the gateway without creating the admin user. Nothing can authenticate with --username / --password until you create a user yourself, and data initialization fails if you enabled it.
Specify the port for the PostgreSQL server.--pg-port [value]Overrides POSTGRESQL_PORT environment variableINT9712Specify the port for the PostgreSQL server.
Specify whether to allow external connections to PostgreSQL.--allow-external-connections [value]Overrides ALLOW_EXTERNAL_CONNECTIONS environment variabletrue, falsefalseOpens the container's internal PostgreSQL server to all interfaces and adds a permissive host-based authentication rule (host all all 0.0.0.0/0 scram-sha-256), which lets any role reach any database from any address with a password. It only changes configuration inside the container, so you also need to publish the PostgreSQL port - for example -p 9712:9712 - to connect from the host. Ignored when --start-pg false. This does not affect the gateway, which always listens on all interfaces on the DocumentDB port.
Specify the path to a certificate for securing traffic.--cert-path [value]Overrides CERT_PATH environment variable.STRINGNAPEM-format certificate. Must be set together with --key-file - setting only one of the two fails at startup. You need to mount this file into the container. For example, to set /mycert.pem, add this option to docker run command: --mount type=bind,source=./mycert.pem,target=/mycert.pem.
Override default key with key in key file.--key-file [value]Overrides KEY_FILE environment variable.STRINGNAPEM-format private key. Must be set together with --cert-path - setting only one of the two fails at startup. You need to mount this file into the container. For example, to set /mykey.key, add this option to docker run command: --mount type=bind,source=./mykey.key,target=/mykey.key
Set the TLS mode for client connections.--tlsMode [value]Overrides TLS_MODE environment variabledisabled, allowTLS, requireTLSallowTLSWith allowTLS the gateway accepts both plain and TLS connections; disabled behaves the same way. requireTLS rejects plain connections, so every client must connect with tls=true.
Enable initialization with built-in sample data.--init-data [value]Overrides INIT_DATA environment variabletrue, falsefalseLoads the StoreData dataset once per fresh data volume. Use a new, empty volume to seed again; see Built-in sample data.
Specify a directory of scripts for database initialization.--init-data-path [value]Overrides INIT_DATA_PATH environment variableSTRING/init_doc_db.dJavaScript files run alphabetically using mongosh, once per fresh data volume. Syntax or runtime errors abort initialization. An attempted script run is not repeated on restart, so fix the scripts and use a fresh volume to retry.
Skip initialization with built-in sample data.--skip-init-dataOverrides SKIP_INIT_DATA environment variabletrue, false (SKIP_INIT_DATA only - the flag itself takes no value)N/ALegacy alias for --init-data false. Note that SKIP_INIT_DATA=false does the opposite of the flag: with INIT_DATA unset it enables the built-in sample data. Does not affect --init-data-path.
Disable the use of extended RUM for indexes.--disable-extended-rumOverrides DISABLE_EXTENDED_RUM environment variableN/A (takes no value)N/AExtended RUM is enabled by default. Known issue: this flag does not currently disable it - the container still starts with documentdb_extended_rum configured.
Enable telemetry data.--enable-telemetry [value]Overrides ENABLE_TELEMETRY environment variabletrue, falsefalseKnown issue: the value is validated at startup but no telemetry is currently emitted - the gateway's metrics and tracing exporters are disabled in this image, and an invalid value only serves to abort startup.
Specify log verbosity.--log-level [value]Overrides LOG_LEVEL environment variable.quiet, error, warn, info, debug, traceinfoKnown issue: the value is validated at startup but does not currently change what the container logs. To change the gateway's own verbosity, set the DOCUMENTDB_LOG_LEVEL environment variable instead; it takes a tracing filter such as info or debug (quiet is not one of its values).

--skip-init-data and --disable-extended-rum are the only options that take no value. Passing one anyway - for example --disable-extended-rum false - is rejected as an unexpected argument and the container exits.

A complete docker run showing where each kind of option goes - Docker options before the image name, container arguments after it. This is the command from the Running section above with a persistent volume and sample data added, so remove that container first with docker rm -f docdb:

docker run -dt \
  -p 127.0.0.1:10260:10260 \
  -v documentdb-data:/data \
  --name docdb \
  ghcr.io/documentdb/documentdb/documentdb-local:pg17-0.117.0 \
  --username "${DOCUMENTDB_USERNAME:?Set DOCUMENTDB_USERNAME first}" \
  --password "${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD first}" \
  --init-data true

Built-in sample data

Release 0.117 replaces the earlier small sampledb seed with the complete StoreData dataset. Loading remains opt-in: add --init-data true to the container arguments, as in the example above.

CollectionDocuments
StoreData.stores41,505
StoreData.ratings2

The bundled Extended JSON preserves BSON Binary, Date, and Timestamp values. After the ready banner, inspect the collections with mongosh:

db.getSiblingDB("StoreData").stores.countDocuments({})   // 41505
db.getSiblingDB("StoreData").ratings.countDocuments({})  // 2

Seeding remains one-shot per data volume. Previously seeded volumes are not automatically migrated to StoreData; use a new, empty volume when you want the new sample dataset. A direct loader rerun tolerates duplicate keys rather than duplicating documents. See the versioned sample-data guide for manual loader instructions.

Container image tags

The latest tag is a convenience alias. Pin an explicit tag for anything reproducible:

TagContents
ghcr.io/documentdb/documentdb/documentdb-local:pg18-0.117.0DocumentDB 0.117.0 on PostgreSQL 18
…:pg17-0.117.0DocumentDB 0.117.0 on PostgreSQL 17
…:pg16-0.117.0 · …:pg15-0.117.0PostgreSQL 16 and 15
…:latestCurrently identical to pg17-0.117.0

latest tracks PostgreSQL 17, while the documentdb package on Linux pins PostgreSQL 18. If you evaluate in Docker and then deploy from packages, you change major version unless you pin the tag deliberately.

Every image records what it was built from:

docker run --rm --entrypoint cat ghcr.io/documentdb/documentdb/documentdb-local:pg18-0.117.0 /version.txt

Data initialization

DocumentDB Local starts empty. Pass --init-data true to seed the StoreData database with the stores and ratings collections:

docker run -dt -p 127.0.0.1:10260:10260 --name documentdb \
  ghcr.io/documentdb/documentdb/documentdb-local:latest \
  --username '<YOUR_USERNAME>' --password '<YOUR_PASSWORD>' --init-data true

Seeding happens once per data volume, on a fresh volume. Existing volumes are not migrated automatically; re-create the volume to seed again.

Control initialization behavior

RequirementArgEnvDefaultDescription
Load built-in sample data--init-data [true|false]INIT_DATAfalseSeed the StoreData sample collections on a fresh data volume.
Skip built-in sample data--skip-init-dataSKIP_INIT_DATA—Legacy alias for --init-data false. Does not affect --init-data-path.
Run custom initialization scripts--init-data-path [PATH]INIT_DATA_PATH/init_doc_db.dExecute every .js file in the mounted directory with mongosh.

The built-in sample dataset currently includes 41,505 store documents and 2 rating documents.

Use custom initialization scripts

docker run -dt --name documentdb \
  -p 127.0.0.1:10260:10260 \
  -v /path/to/init/scripts:/init_doc_db.d \
  ghcr.io/documentdb/documentdb/documentdb-local:latest \
  --username '<YOUR_USERNAME>' \
  --password '<YOUR_PASSWORD>' \
  --init-data-path /init_doc_db.d

When --init-data-path is provided, DocumentDB Local skips the built-in sample data and runs only the scripts you mounted.

Feature support

Please refer to the documentdb documentation for currently supported features.

Installing certificates

If you do not supply your own certificate with --cert-path and --key-file, DocumentDB Local generates a self-signed certificate on first start and reuses it on subsequent starts of the same container, so docker stop / docker start keeps it stable. Removing and re-creating the container generates a new certificate unless you persist the directory it is stored in. The generated certificate is valid for 365 days and is not renewed automatically - re-create the container, or delete cert.pem from the state directory shown below, to generate a fresh one.

To validate the certificate instead of skipping validation with tlsAllowInvalidCertificates=true, copy it out of the container and point mongosh at it.

Get certificate

The gateway picks its TLS state directory from the first writable candidate. In this image that resolves to a path under the container user's home directory, so no extra options are needed when starting the container. In a bash window, copy the certificate from the container to the local host:

docker cp docdb:/home/documentdb/.local/state/documentdb-gateway/tls/cert.pem ~/documentdb-cert.pem

The gateway logs the path it actually chose on startup. Check there first if the copy reports No such container:path:

docker logs docdb | grep "TLS auto-gen"

To keep the same certificate across re-creating the container, pin the location with DOCUMENTDB_TLS_STATE_DIR and put it inside the data volume. This replaces the container you started earlier, so run docker rm -f docdb first:

docker run -dt \
  -p 127.0.0.1:10260:10260 \
  -v documentdb-data:/data \
  -e DOCUMENTDB_TLS_STATE_DIR=/data/tls \
  --name docdb \
  ghcr.io/documentdb/documentdb/documentdb-local:pg17-0.117.0 \
  --username "${DOCUMENTDB_USERNAME:?Set DOCUMENTDB_USERNAME first}" \
  --password "${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD first}"

Point it inside the data directory rather than at a volume of its own: the entrypoint takes ownership of the data directory on every start, whereas a separate volume is created root-owned and the gateway - which runs as an unprivileged user - cannot write its key there. The trade-off is that the same step runs chmod -R 750 over that directory, so from the second start onwards the private key is group-readable rather than owner-only, and it is included in any backup of the data volume.

Use the certificate with mongosh

mongosh localhost:10260 \
  -u "${DOCUMENTDB_USERNAME:?Set DOCUMENTDB_USERNAME first}" \
  -p "${DOCUMENTDB_PASSWORD:?Set DOCUMENTDB_PASSWORD first}" \
  --authenticationMechanism SCRAM-SHA-256 \
  --tls --tlsCAFile ~/documentdb-cert.pem
Current Mongosh Log ID:	690ce1171181053c6edbf354
Connecting to:		mongodb://<credentials>@localhost:10260/?directConnection=true&serverSelectionTimeoutMS=2000&authMechanism=SCRAM-SHA-256&tls=true&tlsCAFile=%2Fhome%2Fuser%2Fdocumentdb-cert.pem&appName=mongosh+2.5.1
Using MongoDB:		7.0.0
Using Mongosh:		2.5.1
mongosh 2.5.9 is available for download: https://www.mongodb.com/try/download/shell

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

[direct: mongos] test>

Beyond local development

DocumentDB Local runs a single container on one machine, with no replication and no failover, which is what makes it convenient for development and testing. For other ways to run DocumentDB:

  • Kubernetes Operator - run DocumentDB as a replicated service, with automatic failover, backup and restore, and rolling upgrades.
  • Pre-built packages - add the DocumentDB extension to a PostgreSQL server you already run.

Reporting issues

If you encounter issues with using this version of DocumentDB, open an issue in the GitHub repository (https://github.com/documentdb/documentdb/issues) and tag it with the label documentdb-local.