1. Overview
Containers are a technological buzzword in the industry. They’re the basic environment constructs that help to build, share and run our applications. A container is lightweight, platform-independent, and virtualizes the application layer. Today, we even have databases like MySQL, MongoDB, PostgreSQL, and many more in containerized form. However, this tutorial will delve into options for deploying MongoDB with examples.
There are numerous ways of deploying MongoDB as a container. Predominantly, we pull an image directly from the official DockerHub. Also, we can use the docker-compose toolkit that helps us to bring the whole application stack together.
Now let’s get into the nitty-gritty details of it.
2. Using docker-compose
docker-compose is a tool that can quickly bring up a stack of containers in less time than bringing up separate containers individually. It uses a YAML file to add the configuration and create all the app services. However, it uses the Docker engine in the backend to create and run the containers.
2.1. docker-compose Installation
Let’s quickly jump into the installation steps.
First, we’ll need to download docker-compose:
# sudo curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
...
... output truncated ...
...
Next, let’s make the downloaded binary executable:
# sudo chmod +x /usr/local/bin/docker-compose
Now, let’s test the installation to check that it’s working properly:
# docker-compose --version
docker-compose version 1.29.2, build 5becea4c
Great! We’ve installed docker-compose successfully on our machine.
2.2. Building Container Using a Compose File
Let’s build our simple docker-compose file to bring up the MongoDB container instance.
Every docker-compose file mandates the version and services tags, while the volumes and networks tags are optional. Here, the version tag shows the version of the compose file format, while the services tag instructs the container’s configuration:
# vi docker-compose.yml
version: '3.3'
services:
mongo:
ports:
- '27017:27017'
container_name: dkrcomp-mongo
restart: always
logging:
options:
max-size: 1g
environment:
- MONGO_INITDB_ROOT_USERNAME=mongoadmin
- MONGO_INITDB_ROOT_PASSWORD=bdung
image: mongo
For example, we need the mongo container image and port details to bring up the MongoDB services. Further, we also set the DB credentials with the container name.
Let’s create and start the containers using the simple up command:
# docker-compose up
Creating network "b014_default" with the default driver
Creating dkrcomp-mongo ... done
Attaching to dkrcomp-mongo
dkrcomp-mongo | about to fork child process, waiting until server is ready for connections.
dkrcomp-mongo | forked process: 29
dkrcomp-mongo |
dkrcomp-mongo | {"t":{"$date":"2022-06-28T00:22:34.228+00:00"},"s":"I", "c":"CONTROL", "id":20698, "ctx":"-","msg":"***** SERVER RESTARTED *****"}
dkrcomp-mongo | {"t":{"$date":"2022-06-28T00:22:34.234+00:00"},"s":"I", "c":"CONTROL", "id":23285, "ctx":"main","msg":"Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'"}
...
... output truncated ...
...
Let’s look at the created container status using the docker ps command:
# docker ps | grep dkrcomp-mongo
1bd9e76f808a mongo "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 0.0.0.0:27017->27017/tcp, :::27017->27017/tcp dkrcomp-mongo
2.3. Accessing the mongo Container
We also need to install the mongo client to run and access MongoDB:
# sudo apt install mongodb-clients -y
[sudo] password for tools:
Reading package lists... Done
...
... output truncated ...
...
Setting up mongo-tools (3.6.3-0ubuntu1) ...
Setting up mongodb-clients (1:3.6.3-0ubuntu1.4) ...
Next, let’s get the container IP address to access the database using the installed client service. If we issue the docker inspect command, we’ll see the detailed information about the container in JSON format. We can also pick any field from the resultant JSON:
# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 1bd9e76f808a
172.18.0.2
We can log in to MongoDB through the client, using the host and port information of our container:
# mongo --host 172.18.0.2 --port 27017
MongoDB shell version v5.0.9
connecting to: mongodb://172.18.0.2:27017/
MongoDB server version: 5.0.9
WARNING: shell and server versions do not match
> use admin
switched to db admin
> use admin
switched to db admin
> db.auth('mongoadmin', 'bdung')
1
Using db.auth, we can authenticate by providing the credentials defined on the docker-compose file:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use baeldung-comp
switched to db baeldung-comp
> db.articles.insert({"name":"Author1"})
WriteResult({ "nInserted" : 1 })
> db.articles.insert({"name":"Author2"})
WriteResult({ "nInserted" : 1 })
> db.articles.insert({"name":"Author3"})
WriteResult({ "nInserted" : 1 })
After authentication, we can perform day-to-day CRUD operations on the newly created baeldung-comp database. Using the show dbs command, we can see the newly created database, and we can use collection commands to see the data inside the articles collection:
> show dbs
admin 0.000GB
baeldung-comp 0.000GB
config 0.000GB
local 0.000GB
> db
baeldung-comp
> show collections
articles
> db.articles.find()
{ "_id" : ObjectId("62ba4ed934419b61a19c2f75"), "name" : "Author1" }
{ "_id" : ObjectId("62ba4ee134419b61a19c2f76"), "name" : "Author2" }
{ "_id" : ObjectId("62ba4ee334419b61a19c2f77"), "name" : "Author3" }
Congrats! We’ve successfully run the MongoDB container instance using docker-compose.
3. Using mongo Image Through the Terminal
In this section, we’ll look at how to build and access the MongoDB database from the terminal.
First, let’s install the mongo image directly from the DockerHub repository using the docker pull command. Here, the pull command will initially check for the availability of the image depending on the requested machine architecture, and then the image is downloaded to the local machine:
# docker pull mongo
Using default tag: latest
latest: Pulling from library/mongo
d7bfe07ed847: Pull complete
...
... output truncated ...
...
Digest: sha256:37e84d3dd30cdfb5472ec42b8a6b4dc6ca7cacd91ebcfa0410a54528bbc5fa6d
Status: Downloaded newer image for mongo:latest
docker.io/library/mongo:latest
3.1. Running a Container
Now, if we issue the docker run command with a few supporting arguments, Docker will start the MongoDB instance and return to us the unique hash code that we can use to identify the container. Let’s see the full command:
# docker run -d -p 27017:27017 --name some-mongo -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=bdung mongo:latest
029f612c14afc278df23dbcecc0938d99369cc5e81316f4f5251560d994fe585
Let’s dig deeper into the arguments:
- -d runs the container in a detached mode
- –name allows us to set the name of the container instance (for example, –name some-mongo)
- -p publishes the container port to the host machine. The format of the option value is [host-port:container-port] — for example, -p 27017:27017
- -e sets the environment variable as needed by the container. For example, we enabled the root credentials for the database using MONGO_INITDB_ROOT_USERNAME=mongoadmin, MONGO_INITDB_ROOT_PASSWORD=bdung
- Finally, we’ve given the image name mongo:latest to derive the container from mongo with the latest tag
As mentioned earlier, we can use the docker ps command to check the status of the running container. Alternatively, we can use docker ps -a to showcase running and stopped container information:
# docker ps | grep mongo
029f612c14af mongo "docker-entrypoint.s…" 17 seconds ago Up 15 seconds 27017/tcp some-mongo
3.2. Accessing the MongoDB Container
Usually, we access the databases through the clients. However, if we’re accessing the remote machine, we use the host IP and port. On the other hand, we can also access the database by logging into the container. We’ve seen the demonstration of the former in the previous section, and we’ll demonstrate the latter in this section.
Here, the docker exec command creates a BASH session with the running container and keeps the STDIN open in both attached and detached mode.
After logging into the databases, we use db.auth to authenticate the access by providing the credentials defined using environment variables. For all successful authentications, we’ll get the response code 1 as demonstrated below:
# docker exec -it 029f612c14af /bin/bash
root@029f612c14af:/# mongo
MongoDB shell version v5.0.9
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
MongoDB server version: 5.0.9
...
... output truncated ...
...
>
> use admin
switched to db admin
> db.auth('mongoadmin', 'bdung')
1
Now, we can perform day-to-day CRUD operations on the newly created baeldung database. Using the show dbs command, we can see the newly created database, and we can use the collection commands to see the data inside the articles collection:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
> use baeldung
switched to db baeldung
> db.articles.insert({"name":"linux"})
WriteResult({ "nInserted" : 1 })
> show dbs
admin 0.000GB
baeldung 0.000GB
config 0.000GB
local 0.000GB
> db
baeldung
> show collections
articles
> db.articles.find()
{ "_id" : ObjectId("62b8fc643860119dcc5e1e76"), "name" : "linux" }
{ "_id" : ObjectId("62b8fd133860119dcc5e1e77"), "name" : "java" }
{ "_id" : ObjectId("62b8fd173860119dcc5e1e78"), "name" : "spring" }
>
4. Conclusion
In this article, we first described what containers are. Then, we discussed the steps to bring up a MongoDB container using the terminal and the docker-compose tool for multi-container applications.