2

Basically i want to create users while creating the image. So that i can directly start my container in auth mode. The whole process must be automated. Hence i have followed the below process.

I am using mongo docker office images 3.2. My docker file

FROM mongo:3.2
MAINTAINER <name> <mail.com>
LABEL description="Mongo installation."
ADD Changeauthversion.js /home/script/
ADD createadminuser.js /home/script/
ADD createsavpuser.js /home/script/
RUN mongod --fork --logpath /var/log/mongodb.log \
&& sleep 5 \
&&mongo <Databasename> /home/script/Changeauthversion.js \
&& mongo <Databasename> /home/script/createadminuser.js \
&& mongo <Databasename> /home/script/createuser.js \
&& rm -r /tmp/mongodb-27017.sock \
&& rm -r /etc/mongod.conf.orig
ADD mongod.conf.orig /etc/
EXPOSE 5002

Docker run file

docker RUN -v mongoDb:/data/db -p 27018:27017 -p 28017:28017 --name mongodb1 -d platform_mongodb:v1

Changeauthversion.js

db.system.users.remove({});
db.system.version.remove({});
db.system.version.insert({ "_id" : "authSchema", "currentVersion" : 3 });

createadminuser.js

db.createCollection("test");
db.createUser({ user: "user",
pwd: "pwd",
roles: [
{ role: "userAdmin", db: "admin" },
{ role: "userAdminAnyDatabase", db: "admin" },
]
});

createuser.js

db.createUser({ user: "user",
pwd: "pwd",
roles: [
{ role: "readWrite", db: "databasename" } ,
]
});

Log while creating the image

about to fork child process, waiting until server is ready for   connections.
forked process: 7
child process started successfully, parent exiting
MongoDB shell version: 3.2.10
connecting to: admin
MongoDB shell version: 3.2.10
connecting to: admin
Successfully added user: {
    "user" : "admin",
    "roles" : [
            {
                    "role" : "userAdmin",
                    "db" : "admin"
            },
            {
                    "role" : "userAdminAnyDatabase",
                    "db" : "admin"
            }
    ]
}
MongoDB shell version: 3.2.10
connecting to: database
Successfully added user: {
    "user" : "user",
    "roles" : [
            {
                    "role" : "readWrite",
                    "db" : "database"
            }
    ]
}
 ---> 98538e078e6e
Removing intermediate container 2ba4fbe3c493
Step 9 : ADD mongod.conf.orig /etc/
 ---> d9d72e70cf3b
Removing intermediate container 68d9c8d43ae8
Step 10 : EXPOSE 5002
---> Running in c134feaec53c
 ---> 296888ad5d23
Removing intermediate container c134feaec53c
Successfully built 296888ad5d23

When i start the container up and try to login, mongo throws an error:user not found.

Error logs from container

:24:35.160+0000 I NETWORK  [initandlisten] connection accepted from    10.0.2.2:49713 #2 (2 connections now open)
:24:35.165+0000 I ACCESS   [conn2] SCRAM-SHA-1 authentication failed for admin on admin from client 10.0.2.2 ; UserNotFound: Could not find user admin@admin

I have already enabled authorization in mongo.conf file. Which i have copied to the image during its build.

security:
authorization: enabled

Can you let me know what the issue is. Why are the users not reflecting in the container. Is there another approach.

  • 1. Your script names are not accurate 2. setup.sh is missing 3. I found that out trying to test your flow, but even before executing it I'm guessing the db you are running at build time is not written to a persistent layer. – Yaron Idan Nov 03 '16 at 07:12
  • setup.sh is for clustering. Hence i have not added. What do you mean by "db you are running at build time is not written to a persistent layer" – Harish Mallikarjuna Nov 03 '16 at 07:20
  • Whether if its for clustering or any other purpose, it prevents us from retracing your steps and testing your case. – Yaron Idan Nov 03 '16 at 07:24
  • Okey i will remove that. – Harish Mallikarjuna Nov 03 '16 at 07:24
  • 2
    Docker writes all of its data to ephemeral storage, which is basically gone once the container is killed. When you run the container you map it to a persistent volume on your disk, so any changes made *after* running your container will persist after the container shuts down. At build time, however, you don't have access to this volume, and thus all changes made to the db are not saved when the image finishes building. – Yaron Idan Nov 03 '16 at 07:25
  • How do i over come this problem. – Harish Mallikarjuna Nov 03 '16 at 07:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127245/discussion-between-harish-mallikarjuna-and-yaron-idan). – Harish Mallikarjuna Nov 03 '16 at 07:28
  • If the storage was ephemeral. Then the scripts copied while building the image must also be lost. All those are present. – Harish Mallikarjuna Nov 03 '16 at 08:06
  • You make a good point I forgot to mention. The layers created in the dockerfile are persistent, and that is the reason the scripts remain. The DB, however, is mapped the ephemeral part of the container. – Yaron Idan Nov 03 '16 at 08:23
  • @YaronIdan When building an image, the data will be committed to the image. When creating a new docker volume, existing data from the mount point is copied from the image into the new volume. – Matt Nov 03 '16 at 09:50

2 Answers2

3

You can overcome the problem by overriding the mongo:3.2 image CMD directive with your own, and rigging the scripts to run after the image is started. You can also create a shell script to run the container and then docker exec the scripts after the container is started. Either way - the scripts should be executed at run time, not build time.

Yaron Idan
  • 6,207
  • 5
  • 44
  • 66
  • Can you expand on why the scripts should be executed at run time? – Matt Nov 03 '16 at 09:43
  • Sure. starting the mongo instance and executing the scripts while building the docker image writes all of the data to an ephemeral part of the container, and not to a persistent data layer. Causing the changes to be lost after finishing the build process. Running the scripts at runtime will persist the changes, since the docker run command mounts the `/data/db` volume. – Yaron Idan Nov 03 '16 at 09:49
  • Build changes are committed and persisted into the image layer. – Matt Nov 03 '16 at 09:52
  • Running the image as a container after a build might be the ephemeral component your thinking of? – Matt Nov 03 '16 at 09:53
0

How to create a Mongo Docker Image with default collections and data?

If you go through this link. It explains docker behavior with respect to volumes. It also explains why data was not persisted. I have tried it the method shown in the above link works.

Community
  • 1
  • 1