DirectorySecurity AdvisoriesPricing
Sign in
Directory
mongodb-search logo

mongodb-search

packaged by Chainguard

Last changed
Request a free trial

Contact our team to test out this image for free. Please also indicate any other images you would like to evaluate.

Tags
Overview
Comparison
Provenance
Specifications
SBOM
Vulnerabilities
Advisories

MongoDB Search (mongot) is the full-text and vector search server for MongoDB. It runs alongside mongod to build search indexes and serve $search and $vectorSearch queries.

Chainguard Containers are regularly-updated, secure-by-default container images.

Download this Container Image

For those with access, this container image is available on cgr.dev:

docker pull cgr.dev/ORGANIZATION/mongodb-search:latest

Be sure to replace the ORGANIZATION placeholder with the name used for your organization's private repository within the Chainguard Registry.

Compatibility Notes

Chainguard's MongoDB Search container image is comparable to the upstream mongodb/mongodb-community-search image, and runs the same mongot process with the same configuration format. Upstream designates the Community Edition of MongoDB Search a public preview and advises against using it for production deployments; the same applies here, since this image packages that release.

Like most Chainguard containers, it runs as a non-root user -- uid and gid 65532, where the upstream image runs as root -- and includes only the packages needed to run mongot -- bash and busybox, which the launcher itself requires, plus libapr, which lets netty-tcnative bind the system OpenSSL that carries the mongod client connection -- and no package manager. Anyone migrating from the upstream image therefore needs a securityContext that permits that uid. Several differences follow from this:

  • File layout. mongot is installed under /usr/share/java/mongodb-search, the FHS location, rather than /mongot-community. A compatibility package keeps /mongot-community working as a symlink, so command lines, volume mounts, and configuration paths written for the upstream image continue to resolve.
  • No bundled JDK. Upstream ships a private JDK inside the image. This image links bin/jdk to the OpenJDK package instead, so the JVM receives the same security updates as the rest of the image and the image is substantially smaller.
  • Data directory and working directory. The default storage.dataPath is /var/lib/mongot, which exists in the image and is writable by the runtime user. The upstream image declares no volume and leaves its working directory at /; this image sets the working directory to /var/lib/mongot. Nothing in mongot depends on the working directory, but a command line that relies on a relative path will resolve differently.
  • Profiler omitted. Upstream ships an /async-profiler tree, which this image does not: it is a debugging tool with no reference in the community server, and leaving it out keeps the image smaller.

The entrypoint is mongot itself, with the config path supplied as the default argument. Upstream wraps the same call in sh -c, which means arguments passed to docker run reach mongot here but are ignored there. Because the config path is the default argument rather than part of the entrypoint, anything you pass replaces it: docker run <image> --logLevel=DEBUG leaves mongot with no --config and it exits. Pass --config explicitly whenever you pass arguments.

Prerequisites

mongot is not a standalone server. It builds its indexes by replicating from a MongoDB replica set, and it answers queries only through that mongod. To run it you need:

  • A mongod replica set at version 8.2 or later, since earlier releases cannot manage search indexes through mongosh or a driver. See MongoDB Search for the query surface. The walkthrough below uses the mongo shell, which is what the Chainguard mongodb image ships.
  • mongod started with --setParameter mongotHost=<host>:27028 and --setParameter searchIndexManagementHostAndPort=<host>:27028 so it routes $search to mongot, plus --setParameter useGrpcForSearch=true to match the server.grpc listener configured below. The walkthrough also passes --setParameter skipAuthenticationToSearchIndexManagementServer=true, which mongod consults only on its non-gRPC path; it is needed only if you serve mongot without gRPC.
  • A configuration file. mongot has no usable built-in defaults and exits if the file is missing or incomplete. The image ships upstream's sample at /usr/share/java/mongodb-search/config.default.yml, which is the default argument -- but that sample is not runnable as shipped: it puts username and passwordFile directly under replicaSet, and this release requires exactly one of scramAuth or x509 there. Restructure it, or supply your own as the walkthrough does, before starting the image; docker run with no arguments uses the sample and exits.

Getting Started

mongot reads its replication credentials from a file that it requires to be readable only by its owner, so create the secret on a volume owned by the runtime user (65532). Writing it from a short-lived root container avoids needing root on the host. The image pre-creates /etc/mongot/secrets, owned by 65532, as the intended mount point for those files -- it is where upstream's sample config looks for its passwordFile. The walkthrough mounts its own volume at /keys instead, which works equally well as long as the files stay owner-only:

docker network create mongot-demo
docker volume create mongot-keys
secret=$(openssl rand -base64 32 | tr -d '\n')
docker run --rm -u 0 -e SECRET="$secret" -v mongot-keys:/keys \
  --entrypoint bash cgr.dev/ORGANIZATION/mongodb-search:latest -c '
    printf %s "$SECRET" > /keys/keyfile
    cp /keys/keyfile /keys/pwfile
    chown 65532:65532 /keys/keyfile /keys/pwfile
    chmod 400 /keys/keyfile /keys/pwfile'

The secret is generated on the host because the image ships only what mongot needs to run, which does not include openssl. It must be a single line with no trailing newline: the keyfile doubles as mongot's password, and mongot rejects a password file that ends in one.

Start a single-member replica set that knows where mongot will listen:

docker run -d --name mongod --network mongot-demo -v mongot-keys:/keys \
  cgr.dev/ORGANIZATION/mongodb:latest \
    --replSet rs0 --dbpath /data --bind_ip_all --keyFile /keys/keyfile \
    --setParameter mongotHost=mongot:27028 \
    --setParameter searchIndexManagementHostAndPort=mongot:27028 \
    --setParameter useGrpcForSearch=true \
    --setParameter skipAuthenticationToSearchIndexManagementServer=true

Wait for it to accept connections before talking to it:

until docker logs mongod 2>&1 | grep -q "Waiting for connections"; do sleep 2; done

Initiate the set and create an administrative user. Both commands run inside the mongod container because the localhost exception is what permits them while authentication is enabled:

docker exec mongod mongo --quiet --eval \
  'rs.initiate({_id:"rs0",members:[{_id:0,host:"mongod:27017"}]})'

rs.status() reports PRIMARY before the node accepts writes, so wait until it is writable before creating the user; otherwise the write fails with not master:

until docker exec mongod mongo --quiet --eval 'db.hello().isWritablePrimary' \
  | grep -qx true; do sleep 2; done
until docker exec mongod mongo --quiet --eval \
  'db.getSiblingDB("admin").createUser({user:"admin",pwd:"password",roles:["root"]})'
do sleep 2; done

Write a configuration file and start mongot against that replica set:

mkdir -p conf
cat > conf/mongot.conf <<'EOF'
syncSource:
  replicaSet:
    hostAndPort: "mongod:27017"
    scramAuth:
      username: __system
      authSource: local
      passwordFile: /keys/pwfile
storage:
  dataPath: "/var/lib/mongot"
server:
  grpc:
    address: "0.0.0.0:27028"
healthCheck:
  address: "0.0.0.0:8080"
EOF

docker run -d --name mongot --network mongot-demo \
  -v mongot-keys:/keys -v "$PWD/conf:/conf" -p 8080:8080 \
  cgr.dev/ORGANIZATION/mongodb-search:latest --config=/conf/mongot.conf

mongot reports its own readiness on the health endpoint. It syncs from the replica set before it starts serving, so poll until the endpoint answers:

until curl -sf http://localhost:8080/health; do sleep 2; done
{"status":"SERVING"}

Now create a search index and query it:

docker exec mongod mongo --quiet -u admin -p password --authenticationDatabase admin --eval '
  db.getSiblingDB("demo").movies.insertMany([
    {title:"Jurassic World: Fallen Kingdom"},{title:"Tag"}]);
  db.getSiblingDB("demo").runCommand({
    createSearchIndexes:"movies",
    indexes:[{name:"default",definition:{mappings:{dynamic:true}}}]});'

mongot builds the index by replicating the collection, so it answers queries only once it reports READY. Wait for that before querying:

until docker exec mongod mongo --quiet -u admin -p password \
  --authenticationDatabase admin --eval '
    var r = db.getSiblingDB("demo").runCommand({listSearchIndexes:"movies"});
    var d = (r.cursor && r.cursor.firstBatch && r.cursor.firstBatch[0]) || {};
    print(d.status || "NONE")' | grep -qx READY; do sleep 2; done
docker exec mongod mongo --quiet -u admin -p password --authenticationDatabase admin --eval '
  db.getSiblingDB("demo").movies.aggregate([
    {$search:{index:"default",text:{query:"fallen",path:"title"}}},
    {$project:{_id:0,title:1}}]).toArray()'
[ { "title" : "Jurassic World: Fallen Kingdom" } ]

Configuration

mongot is configured entirely through the YAML file passed to --config. The file above is the smallest one that works, and the syncSource block is the part worth understanding: mongot authenticates to mongod as the internal __system user, using the replica set keyfile as its password, which is why passwordFile points at a copy of that keyfile and why authSource is local. Authenticating as a dedicated user is also supported — give that user the searchCoordinator role on admin and point username, authSource (admin, not local) and passwordFile at its credentials instead.

Exactly one authentication mechanism must be present under replicaSet, either scramAuth or x509; a configuration with neither is rejected at startup.

For production deployments on Kubernetes, prefer the MongoDB Controllers for Kubernetes operator and its MongoDBSearch resource over hand-written configuration. The operator generates the configuration, manages the keyfile as a secret, and sets the mongod parameters above for you.

Documentation and Resources

What are Chainguard Containers?

Chainguard's free tier of Starter container images are built with Wolfi, our minimal Linux undistro.

All other Chainguard Containers are built with Chainguard OS, Chainguard's minimal Linux operating system designed to produce container images that meet the requirements of a more secure software supply chain.

The main features of Chainguard Containers include:

For cases where you need container images with shells and package managers to build or debug, most Chainguard Containers come paired with a development, or -dev, variant.

In all other cases, including Chainguard Containers tagged as :latest or with a specific version number, the container images include only an open-source application and its runtime dependencies. These minimal container images typically do not contain a shell or package manager.

Although the -dev container image variants have similar security features as their more minimal versions, they include additional software that is typically not necessary in production environments. We recommend using multi-stage builds to copy artifacts from the -dev variant into a more minimal production image.

Need additional packages?

To improve security, Chainguard Containers include only essential dependencies. Need more packages? Chainguard customers can use Custom Assembly to add packages, either through the Console, chainctl, or API.

To use Custom Assembly in the Chainguard Console: navigate to the image you'd like to customize in your Organization's list of images, and click on the Customize image button at the top of the page.

Learn More

Refer to our Chainguard Containers documentation on Chainguard Academy. Chainguard also offers VMs and Libraries — contact us for access.

Trademarks

This software listing is packaged by Chainguard. The trademarks set forth in this offering are owned by their respective companies, and use of them does not imply any affiliation, sponsorship, or endorsement by such companies.

Licenses

Chainguard's container images contain software packages that are direct or transitive dependencies. The following licenses were found in the "latest" tag of this image:

  • Apache-2.0

  • BSD-3-Clause

  • Bitstream-Vera

  • Classpath-exception-2.0

  • FTL

  • GCC-exception-3.1

  • GPL-2.0

For a complete list of licenses, please refer to this Image's SBOM.

Software license agreement

Compliance

Chainguard Containers are SLSA Level 3 compliant with detailed metadata and documentation about how it was built. We generate build provenance and a Software Bill of Materials (SBOM) for each release, with complete visibility into the software supply chain.

SLSA compliance at Chainguard

This image helps reduce time and effort in establishing PCI DSS 4.0 compliance with low-to-no CVEs.

PCI DSS at Chainguard

A FIPS validated version of this image is available for FedRAMP compliance. STIG is included with FIPS image.


Related images
mongodb-search-fips logoFIPS

mongodb-search-fips


Category
Application

The trusted source for open source

Talk to an expert
PrivacyTerms

Product

Chainguard ContainersChainguard LibrariesChainguard VMsChainguard OS PackagesChainguard ActionsChainguard Agent SkillsIntegrationsPricing
© 2026 Chainguard, Inc. All Rights Reserved.
Chainguard® and the Chainguard logo are registered trademarks of Chainguard, Inc. in the United States and/or other countries.
The other respective trademarks mentioned on this page are owned by the respective companies and use of them does not imply any affiliation or endorsement.