# MongoDB

## Prerequisites

* [x] **The primary key (`_id`) must be a unique, auto-generated** [**ObjectId**](https://www.mongodb.com/docs/manual/reference/bson-types/#std-label-objectid)**.**\
  MongoDB's built-in [ObjectId](https://www.mongodb.com/docs/manual/reference/bson-types/#std-label-objectid) is the only data type we support for MongoDB collections' primary keys.&#x20;
* [x] **MongoDB must be running as part of a** [**Replica Set**](https://www.mongodb.com/docs/manual/replication/) **for Stacksync to detect changes from MongoDB**
  * If you use the **Atlas Database**, no further action is needed.
  * If you **self-host**, or use a **different managed service**, make sure the MongoDB is configured as a *replica set* by running `rs.status()` in a MongoDB shell. This is required [*even if you only have a single node*](https://www.mongodb.com/community/forums/t/using-change-streams-in-a-standalone-database/127281/2). \
    \
    1\. To set up a single-node replica set, run:\
    `mongod --port 27017 --dbpath /path/to/data --replSet rs0 --auth --keyFile /path/to/keyfile`\
    This assumes you've already set up a key file, otherwise do:\
    `echo "<YOUR_SECRET>" > /path/to/keyfile`\
    2\. Connect to the instance:\
    `mongosh "mongodb://localhost:27017"` (don't forget to add username and password)\
    3\. Once inside the instance, you have to go through replica set configuration at least once. A simple example could be:\
    `rs.initiate({ _id: "rs0", members: [{ _id: 0, host: "localhost:27017" }] })`.\
    \
    Check out [the official documentation](https://www.mongodb.com/docs/manual/tutorial/deploy-replica-set/#std-label-server-replica-set-deploy) for more information.

{% hint style="success" %}
The [oplog](https://www.mongodb.com/docs/manual/core/replica-set-oplog/) and [change streams](https://www.mongodb.com/docs/manual/changeStreams/) are built-in tools managed by MongoDB and leveraged by Stacksync to track changes to your data in real time. Enabling replication is required to make them available.
{% endhint %}

* [x] **Allow Stacksync IPs**\
  Stacksync services must be able to access your MongoDB instance(s). To avoid issues, make sure to whitelist [Stacksync's public IPs](https://docs.stacksync.com/two-way-sync/connectors/setup-options/ip-whitelisting).&#x20;
* [x] **A MongoDB user with the required permissions.**\
  The provided MongoDB user should be able to **create collections, read and write from them and also access the oplog.**\
  In order to sync, track changes and keep data sources updated, these are necessary. Otherwise, data cannot be accessed.\
  \
  \- For **Atlas Database**, follow [the official documentation](https://www.mongodb.com/docs/atlas/security-add-mongodb-users/#add-database-users).\
  \- For all other deployments, you can run:

{% hint style="info" %}
We strongly suggest using MongoDB's built-in [`read`](https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-read) or [`readWrite`](https://www.mongodb.com/docs/manual/reference/built-in-roles/#mongodb-authrole-readWrite) roles. For more information on how to [create](https://www.mongodb.com/docs/manual/reference/command/createUser/#mongodb-dbcommand-dbcmd.createUser) and [grant roles](https://www.mongodb.com/docs/manual/reference/command/grantRolesToUser/) to users, check out [MongoDB's official documentation](https://www.mongodb.com/docs/manual/reference/database-users/).
{% endhint %}

<pre class="language-mongodb"><code class="lang-mongodb">// Grant user roles without overwriting existing ones (specific DBs)
use admin

<strong>const user = db.getUser("&#x3C;user>");  // Change to your username
</strong>
const updatedRoles = user.roles.concat([
        { role: "read", db: "local" }, // required to read the oplog and therefore read changes from mongodb
        { role: "readWrite", db: "&#x3C;db1>" }, // when need to read and write to mongodb
        { role: "read", db: "&#x3C;db2>" }, // when do not need to write to mongodb
        // Add the database(s) you want Stacksync to have access to
      ]);

db.updateUser("&#x3C;user>", { roles: updatedRoles });
</code></pre>

{% hint style="warning" %}
Access must be given at the **database level** for changes to be correctly replicated. Individual collection access is not currently supported.
{% endhint %}

If a collection you see in your database does not appear in Stacksync, or changes are not correctly replicated, one of the previous conditions is not met. Please double-check your setup in that case.

If you have any questions, don't hesitate to contact us at <hello@stacksync.com>.

## Connecting your MongoDB instance

To connect your MongoDB database to Stacksync, you'll need the following data:

{% hint style="success" %}
You can either enter these fields individually or **simply paste your** [**connection string**](#connection-strings) **directly**. We'll take care of the rest.
{% endhint %}

* **Protocol**: must be `mongodb+srv://` or `mongodb://`.
* **Host**: the URI or IP where the server can be found.
* **Port** (optional): the default is usually `27017`.
* **Authentication method**

  * **Username**: name used to authenticate with the server.
  * **Password**: the password used to authenticate with the server.

  or

  * **TLS/SSL** (X.509 Certificate): you must upload your public .pem file. In MongoDB Atlas [you can download it when you create the user](https://www.mongodb.com/docs/atlas/security-add-mongodb-users/#add-database-users):

  <figure><img src="https://2867423571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfJjIdV9cuW6K8asJjTPJ%2Fuploads%2F059fEMYJjscDU8ZRt3o4%2Fimage.png?alt=media&#x26;token=2262f285-1317-4ce6-b1d1-b90833239a4f" alt="" width="375"><figcaption></figcaption></figure>
* **Database**: the name of the database where data is present.
* Connection options:
  * [**Replica Set**](https://www.mongodb.com/docs/manual/reference/connection-string-options/#replica-set-option) (optional): allows you to specify the name of the replica set to connect to.
  * [**Auth Database**](https://www.mongodb.com/docs/manual/reference/connection-string-options/#mongodb-urioption-urioption.authSource) (optional): the database that holds the user's info. The default is `admin` for username & password, and `$external` for TLS.

{% hint style="info" %}
Other connection options are not currently supported. If you need special assistance, please contact us at <hello@stacksync.com>.
{% endhint %}

* **SSH Tunnel**:
  * **Username**: The user Stacksync can identify as to establish the tunnel.
  * **Host**: IP of the machine to SSH into.
  * **Public Key**: Copy into your machine's `~/.ssh/authorized_keys` file. You can use [ssh-copy-id](https://www.ssh.com/academy/ssh/copy-id) or simply SSH into the server and paste it using your preferred text editor.

{% hint style="info" %}
SSH tunneling is currently only supported for single, self-hosted MongoDB instances via the mongodb:// protocol. For any further questions, please contact us at <hello@stacksync.com>.
{% endhint %}

<div><figure><img src="https://2867423571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfJjIdV9cuW6K8asJjTPJ%2Fuploads%2FSZiaRZRe6CqEPLJIXsvE%2FScreenshot%202025-04-15%20133510.png?alt=media&#x26;token=1d8255af-c5d5-4a9b-81e0-ec8112841d45" alt="" width="375"><figcaption><p>The connection setup screen for user+password</p></figcaption></figure> <figure><img src="https://2867423571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfJjIdV9cuW6K8asJjTPJ%2Fuploads%2FhvUURGvmN6WQJfmQC8OS%2FScreenshot%202025-04-15%20134301.png?alt=media&#x26;token=dbd38565-a6d7-43d9-a4dc-4c26a4e3e90d" alt="" width="375"><figcaption><p>The connection setup screen for TLS/SSL</p></figcaption></figure></div>

### Connection strings

MongoDB has 2 formats for their [connection strings](https://www.mongodb.com/docs/manual/reference/connection-string/). Make sure to pick the one that best suits your use case.

{% hint style="success" %}
If you're not sure which format to use, **we recommend using the (newer) SRV format**.
{% endhint %}

* **SRV**: `mongodb+srv://[username:password@]host[/[defaultauthdb][?options]]` *(elements in brackets* `[]` *are optional)*
  * Example: `mongodb+srv://myDatabaseUser:D1fficultP%40ssw0rd@cluster0.example.mongodb.net/?retryWrites=true&w=majority`
* **Standard**: `mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]` *(elements in brackets* `[]` *are optional)*
  * Example: `mongodb://myDatabaseUser:D1fficultP%40ssw0rd@mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?authSource=admin&replicaSet=myRepl`

Find more examples [here](https://www.mongodb.com/docs/manual/reference/connection-string-examples/#std-label-connections-connection-examples).

### Getting your connection string

To find out your connection string, check out MongoDB's [official guide for MongoDB Atlas](https://www.mongodb.com/docs/guides/atlas/connection-string/), or [their guide for self-hosted clusters](https://www.mongodb.com/resources/products/fundamentals/mongodb-connection-string#connection-strings-for-a-self-hosted-mongodb-cluster).

If you have any questions, don't hesitate to contact us at <hello@stacksync.com>, we're happy to help!
