Deploy MongoDB with Docker
- 0. Prerequisites
- 1. Start a MongoDB Instance.
- 2. Start a MongoDB Instance with Access Control.
- 3. Deploy a Replica Set
- 4. Deploy a Replica Set with Access Control.
- References:
0. Prerequisites
Make sure you have already installed both Docker Engine and Docker Compose. You don’t need to install MongoDB, as it’s provided by Docker image.
1. Start a MongoDB Instance.
$ docker run -d -p 27017:27017 --name db mongo:3
2. Start a MongoDB Instance with Access Control.
$ docker run -d -p 27017:27017 --name db mongo:3 --auth
Connect a mongo shell to one of the config server mongod instances over the localhost interface and create the user administrator.
$ docker exec -it db mongo admin --quiet
> db.createUser({
... user:"admin",
... pwd:"admin",
... roles: [
... {role: "userAdmin", db:"admin"}
... ]
... })
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdmin",
"db" : "admin"
}
]
}
> db.auth("admin","admin")
1
> db.createUser({
... user: "user1",
... pwd: "user1",
... roles: [
... {
... role: "readWriteAnyDatabase",
... db: "admin"
... }
... ]
... })
Successfully added user: {
"user" : "user1",
"roles" : [
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
}
]
}
> use test
switched to db test
> db.test.insertOne({ x: 1 })
2017-09-08T08:50:53.276+0000 E QUERY [thread1] TypeError: err.hasWriteErrors ...
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:244:13
@(shell):1:1
> db.auth("user1","user1")
Error: Authentication failed.
0
> use admin
switched to db admin
> db.auth("user1","user1")
1
> use test
switched to db test
> db.test.insertOne({ x: 1 })
{
"acknowledged" : true,
"insertedId" : ObjectId("59b25a108bcdfe4e19c35a13")
}
>
3. Deploy a Replica Set
$ mkdir mogors
$ cd mogors/
$ cat <<EOF > docker-compose.yml
> ---
> version: "3.2"
> services:
> db-0:
> container_name: db-0
> image: mongo:3
> # Start each member of the replica set with the appropriate options .
> command:
> - mongod
> - "--replSet"
> - "rs0"
> db-1:
> container_name: db-1
> image: mongo:3
> command:
> - mongod
> - "--replSet"
> - "rs0"
> db-2:
> container_name: db-2
> image: mongo:3
> command:
> - mongod
> - "--replSet"
> - "rs0"
> EOF
$ docker-compose up -d
Creating network "mongors_default" with the default driver
Creating db-2 ...
Creating db-0 ...
Creating db-1 ...
Creating db-2
Creating db-1
Creating db-0 ... done
$ docker ps -a
CONTAINER ID IMAGE STATUS PORTS NAMES
0f6a34b826b2 mongo:3 Up 45 seconds 27017/tcp db-1
c4c04bfc53f3 mongo:3 Up 46 seconds 27017/tcp db-0
9d8bc021082c mongo:3 Up 46 seconds 27017/tcp db-2
$ docker exec -it db-0 mongo --quiet
> rs.initiate( {
... _id : "rs0",
... members: [ { _id : 0, host : "db-0" } ]
... })
{ "ok" : 1 }
rs0:PRIMARY> rs.add("db-1")
{ "ok" : 1 }
rs0:PRIMARY> rs.add("db-2")
{ "ok" : 1 }
rs0:PRIMARY> db.runCommand("isMaster")
{
"hosts" : [
"db-0:27017",
"db-1:27017",
"db-2:27017"
],
"setName" : "rs0",
"setVersion" : 3,
"ismaster" : true,
"secondary" : false,
"primary" : "db-0:27017",
"me" : "db-0:27017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1504859331, 1),
"t" : NumberLong(1)
},
"lastWriteDate" : ISODate("2017-09-08T08:28:51Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2017-09-08T08:28:56.329Z"),
"maxWireVersion" : 5,
"minWireVersion" : 0,
"readOnly" : false,
"ok" : 1
}
rs0:PRIMARY>
4. Deploy a Replica Set with Access Control.
$ mkdir mogors
$ cd mogors/
$ # Create a keyfile.
$ openssl rand -base64 756 > keyfile
$ cat keyfile
AFO3EYmmmQQLF68tUd3aQsFI/C53XtOpUGt8R5ecS1F9uWRFg4dN6jlCjiBbYqHC
w3lqUhlRBe00YhDM97z31oYkQBSyID20pIMeQ3e40FY6zBE1w+4lWYekuPJAUtzS
ZspGfFExltwL0700Dwu7b1mnMbqfmfrpSVxTKHaY7Hcw60mvbBPPCp6IWkDVZ9NX
NKveHX3Wuq28/PSMw8sVPUbP5eqPux05PCyp5VBp6/fhg8Np8vIlWAy9fMsAgkmE
kBeGcRNst6t0iXbqNi9VrW6szJN5yyq0x1+0XB1QJZCjnLczoXMTPQeDCTrijbpI
N4zr7L2EV6n8FsgSJ7vwzRMj0ZRFjuK/wwBblPCuisv5JlcClZ6I0WEtV1yg5HQu
AFv3v7FPmfodQ6Sz81c6sNEKuwg3kzCY7wkeA163RZrujHViYFka6zOcv/kDdQ5h
rL6EBXE3v6bnd24/nzys9Zx6CrqPPUqSVfugmIW78r9imXswUqdr/VZVbhGsKcjH
Uza306prvuWmh0o1hpFGReGbHIdWhEtP/ldXKBbPy+27tgNeSiSP1GjVG2rkaIlb
bsnahiNj2EaAa1ov9pYiyO51m+ouEg+H9LPBcLhLXipI3wbST8BqMZweLSNfeLFi
Kpel5Q3rNtmRrjCbVIiiAXmxECU+PcwL+a4XhISnktdq6Du43d4INSJ/cn8JVLFS
VbR5nTnc4cMmEE3n/0BrScZinGZT1gbtwbE5izA5E17/7n/HLGUXhfhMGWrwdL9f
CsDt8ZEg7AUCPhFhsbcwfHkROXmYYubcd41NqLEYyktDzqsu3CaXFvH3QyD5AqmN
ylh6UGgjqgWIC7y553qNE9v7Go/9zKTUj8Df/wcQVl6ALOdZgPmchNTX8PtENdKT
aPUu/dcctYZUxz1DKwkaH3aUblSBGtSHa94knUA+R3DWPTcGNt3n46AL45Ty5amX
c5yYTpaKB6jgXwIMjO96OA9XlZKxOVgqdASsN6O0wCzfAg55
$ chmod 400 keyfile
$ sudo chown 999 keyfile
$ cat docker-compose.yml
---
version: "3.2"
services:
db-0:
container_name: db-0
image: mongo:3
# Start each member of the replica set with the appropriate options .
command:
- mongod
- "--replSet"
- "rs0"
- "--auth"
- "--keyFile"
- "/opt/mongors/keyfile"
volumes:
- type: bind
source: ./keyfile
target: /opt/mongors/keyfile
read_only: true
db-1:
container_name: db-1
image: mongo:3
command:
- mongod
- "--replSet"
- "rs0"
- "--auth"
- "--keyFile"
- "/opt/mongors/keyfile"
volumes:
- type: bind
source: ./keyfile
target: /opt/mongors/keyfile
db-2:
container_name: db-2
image: mongo:3
command:
- mongod
- "--replSet"
- "rs0"
- "--auth"
- "--keyFile"
- "/opt/mongors/keyfile"
volumes:
- type: bind
source: ./keyfile
target: /opt/mongors/keyfile
$ docker-compose up -d
Creating network "mongors_default" with the default driver
Creating db-1 ...
Creating db-0 ...
Creating db-1
Creating db-0
Creating db-2 ...
Creating db-2 ... done
$ docker ps -a
CONTAINER ID IMAGE STATUS PORTS NAMES
02143821d0d7 mongo:3 Up 3 seconds 27017/tcp db-2
338aef4ef282 mongo:3 Up 3 seconds 27017/tcp db-0
ff459a50af25 mongo:3 Up 3 seconds 27017/tcp db-1
$ docker exec -it db-0 mongo --quiet
> rs.initiate( {
... _id : "rs0",
... members: [ { _id : 0, host : "db-0" } ]
... })
{ "ok" : 1 }
rs0:SECONDARY> use admin
switched to db admin
rs0:PRIMARY> db.createUser({
... user:"admin",
... pwd:"admin",
... roles: [
... {role: "userAdmin", db:"admin"},
... {role: "clusterAdmin", db: "admin"}
... ]
... })
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "userAdmin",
"db" : "admin"
},
{
"role" : "clusterAdmin",
"db" : "admin"
}
]
}
rs0:PRIMARY> rs.add('db-1')
2017-09-08T09:44:33.194+0000 E QUERY [thread1] Error: count failed: {
"ok" : 0,
"errmsg" : "not authorized on local to execute command ...
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DBQuery.prototype.count@src/mongo/shell/query.js:383:11
DBCollection.prototype.count@src/mongo/shell/collection.js:1700:12
rs.add@src/mongo/shell/utils.js:1227:1
@(shell):1:1
rs0:PRIMARY> db.auth('admin','admin')
1
rs0:PRIMARY> rs.add('db-1')
{ "ok" : 1 }
rs0:PRIMARY> rs.add('db-2')
{ "ok" : 1 }
rs0:PRIMARY> db.runCommand("isMaster")
{
"hosts" : [
"db-0:27017",
"db-1:27017",
"db-2:27017"
],
"setName" : "rs0",
"setVersion" : 3,
"ismaster" : true,
"secondary" : false,
"primary" : "db-0:27017",
"me" : "db-0:27017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1504863894, 1),
"t" : NumberLong(1)
},
"lastWriteDate" : ISODate("2017-09-08T09:44:54Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2017-09-08T09:45:04.775Z"),
"maxWireVersion" : 5,
"minWireVersion" : 0,
"readOnly" : false,
"ok" : 1
}
rs0:PRIMARY>
References:
- mongo | Docker Documentation
- Enable Auth — MongoDB Tutorials
- Manage Users and Roles — MongoDB Tutorials
- Built-In Roles — MongoDB Manual 3.4
- Deploy a Replica Set — MongoDB Manual 3.4
- Enforce Keyfile Access Control in a Replica Set — MongoDB Manual 3.4
- Compose file version 3 reference | Docker Documentation
- Deploy a MongoDB Cluster in 9 steps Using Docker
- Mongodb KeyFile too open permissions - Stack Overflow