Multiple local development databases

I know that the Meteor test enviroment uses a different MongoDB for test data, which is super helpful. So there must be a way to temporarily switch the local Mongo DB to a new set of files.

Is there a way to accomplish this for the regular dev server as well? I would like to host multitple versions of our app’s database, so I can switch between them, without hosting a full local Mongo installation.

Yes it’s possible. I use a simple shell script that utilizes the bundled MongoDB with parameters pointing to a different db files location.

I’ll post it when I get to my laptop.

The local dev db is stored in [your project folder]/.meteor/local/db.

When I want to try running with a fresh db then I rename this folder (e.g. "db.old") and on startup Meteor creates a fresh new "db" folder. Then to switch back I just kill Meteor, rename the new one to "db.new" and revert "db.old" back to "db" and restart Meteor.

You could automate this with separate commands in your package.json so you can run with a specified database folder depending on which "npm run ..." command you run. In which case using symlinks instead of renaming folders might be better.

1 Like

It’d be nice if Meteor could be given the database name somehow, so it’d still start the MongoDB itself, but operate on different databases (within the same files locally). We achieve the same using Docker - we start the database once and then can start both standard and test app at once, using the same MongoDB instance.

Has anyone tried spinning up a local mongo server and then running meteor locally with the MONGO_URL environment variable pointing to it? Should work… (docs). @radekmie, is that what you’re doing with Docker?

Yep. Here’s the docker-compose.yml part:

version: '3.7'
services:
  mongo:
    image: mongo:6.0.4 # It also works with 4.4, and 5.0
    command: --config /etc/mongod.conf
    ports:
      - 27017:27017
    healthcheck:
      test: |
        # MongoDB < 6.0
        test $$(echo "rs.status().ok || rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'mongo:27017' }] }).ok" | mongo --quiet) -eq 1
        # MongoDB >= 6.0
        test $$(mongosh --quiet --eval "rs.initiate({ _id: 'rs0', members: [{ _id: 0, host: 'mongo:27017' }] }).ok") -eq 1
      interval: 10s
      start_period: 10s
    volumes:
      - ./config/mongo/mongod.conf:/etc/mongod.conf:ro
      - mongo-data:/data/db
volumes:
  mongo-data:

And here’s the config/mongo/mongod.conf:

cloud:
  monitoring:
    free:
      state: off
net:
  bindIpAll: true
replication:
  oplogSizeMB: 64
  replSetName: rs0
setParameter:
  quiet: 1
systemLog:
  quiet: true

Then start your app with:

MONGO_URL=mongodb://0.0.0.0:27017/DATABASE_NAME

We use it for a long time now and it works really well. We also have a couple of other services we start there (e.g., redis for cultofcoders:redis-oplog together with oplogtoredis) and it’s fairly easy. It’s also nice for the CI, as you can start these and the background and run your tests as usual.

Thinks can be so simple. Thanks for pointing that out.