Skip to content

Instantly share code, notes, and snippets.

@eric-do
Last active January 25, 2023 19:26
Show Gist options
  • Save eric-do/813d3142203a407d63ed60bc1739b8cb to your computer and use it in GitHub Desktop.
Save eric-do/813d3142203a407d63ed60bc1739b8cb to your computer and use it in GitHub Desktop.
Guide for installing Mongo via Docker

Installing Mongo 4.4 via Docker

TLDR: just looking for the code? Skip to the end.

🐳 Installing Docker

Download Docker Desktop here.

πŸ“€ Pulling and containerizing a mongo server instance

Make sure Docker is running.

The following command will pull an image of mongo if one doesn't exist, then create a container for it.

docker run --name some-mongo -p 27017:27017 -d mongo:4.4

If containerization was successful, you should see the container when you run docker ps -a from your terminal.

CONTAINER ID   IMAGE                     COMMAND                  CREATED             STATUS                       PORTS                               NAMES
1b5dea6eb2f0   mongo:4.4                 "docker-entrypoint.s…"   12 seconds ago      Up 10 seconds                0.0.0.0:27017->27017/tcp            some-mongo

Explanation of the flags above

  • --name: container name. In the example above, some-mongo is the name of your container. We typically only need one database container, but if you want your containers to be project based, consider something like groceries-db
  • -p: port mapping <host_port>:<container_port>. Mongo runs on port 27017 inside the container, i.e. port 27017 on your localhost doesn't automatically connect to the database. If you want your local port 27017 to point to the container's port 27017, you need to specify it.

At this point you will have a running container with Mongo running inside of it. You can connect to the database from your local node application. If you don't know how, the next sections detail how to connect to your container as well as to your database.

πŸ‘¨πŸ»β€πŸ’» Running commands inside the Docker container

Assume the same some-mongo container name as before. Note that you can also open the CLI from Docker Desktop.

docker exec -it some-mongo bash

With the container's CLI running, you can login to your Mongo database.

MacBook-Pro:~ ericdo$ docker exec -it some-mongo bash
root@1b5dea6eb2f0:/# mongo
MongoDB shell version v4.4.15
MongoDB server version: 4.4.15
Welcome to the MongoDB shell.

> show dbs
admin    0.000GB
config   0.000GB
fetcher  0.000GB
local    0.000GB

πŸ§ͺ Testing your connection

You should now also be able to connect directly to the containerized database from your node application.

You can put this code wherever you connect your database, e.g. in database/index.js.

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/fetcher'); // change "fetcher" to your DB name

If the connection is successful, no error will be thrown.

πŸ›Ÿ Persisting your data

Your data will be saved even when you stop your containers.

The only thing you do need to worry about is when you remove your containers, e.g. rm -rf <container id>. This is the equivalent of uninstalling the database, so data may not persist then.

You shouldn't need to remove your database container unless you're upgrading/downgrading database versions or specifically want to delete the database instance. Persisting data across such scenarios is done with volumes, which are outside of scope of this installation guide for now.

🐞 Troubleshooting

Cannot connect to database server

Example error message when using Mongoose:

UnhandledPromiseRejectionWarning: MongoNetworkError: failed to connect to server [localhost:27017] on first connect [Error: connect ECONNREFUSED 127.0.0.1:27017

Your container may have stopped.

  • Confirm container statuses with: docker ps -a
  • Restart the relevant container if it has status Exited with: docker start <CONTAINER ID>
$ docker ps -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS                       PORTS                               NAMES
1b5dea6eb2f0   mongo:4.4                 "docker-entrypoint.s…"   7 days ago      Exited (0) 2 minutes ago                                         some-mongo

$ docker start 1b5dea6eb2f0
1b5dea6eb2f0

Application successfully pulls data, but data is not shown in CLI

If you have a local installation (not installed with Docker) of your database, it may be running on the same port 27017.

  • Confirm services running on port 27017: lsof -i tcp:27017
  • kill unneeded services: kill <PID>
  • Restart our Dockerized container: docker restart <CONTAINER ID>
$ lsof -i tcp:27017
COMMAND     PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.docke 16558 ericdo  128u  IPv6 0xf8014bcbf1ced6b7      0t0  TCP *:27017 (LISTEN)
mongod    45795 ericdo    9u  IPv4 0xf8014bda59f55517      0t0  TCP localhost:27017 (LISTEN)

$ kill 45795
$ docker restart 1b5dea6eb2f0

Note in the example above, mongod is running. We only want our Dockerized instance of the database running, so kill the mongod process then restart the Dockerized container.

⏰ TLDR

If this is your first time reading this document, do not go directly to this section unless you just want to get lost, break things, and learn the hard way.

Pull image and run container

  1. Install Docker
  2. docker run --name some-mongo -p 27017:27017 -d mongo:4.4
  3. Connect your application

List all containers

docker ps -a

Container lifecycle

docker start <CONTAINER ID>
docker restart <CONTAINER ID>
docker stop <CONTAINER ID>
docker rm -rf <CONTAINER ID>

You can remove a container anytime as long as you've stopped it. You should not remove a container unless you want to delete that database instance or want to upgrade/downgrade database versions.

Access container CLI and database CLI

docker exec -it <CONTAINER NAME> bash
mongo
@cngondo
Copy link

cngondo commented Aug 13, 2022

@eric-do Slight concern when we want to persist data and students happen to stop running containers. Perhaps a branch of instructions to include this bit using volumes, especially because we are doing this on sprints heavy on data persistence.

@eric-do
Copy link
Author

eric-do commented Aug 15, 2022

Hi @cngondo, thanks for giving this a thorough read and for the suggestion!

Data persists when containers are stopped/restarted. The containers will lose data only if they're removed. I'm not sure if there's a need to remove DB containers (equivalent of uninstalling the database), and if so, whether it's important to persist data between removals? Especially in the junior curriculum, data is only needed for 2 days at a time during sprints.

Since these are simple installation and usage guides, I think I can cover volumes in an advanced guide, if needed. Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment