I'm new to docker and mongoDB, so I expect I'm missing some steps. Here's what I have in my Dockerfile so far:
FROM python:2.7 RUN apt-get update \ && apt-get install -y mongodb \ && rm -rf /var/lib/apt/lists/* RUN mkdir -p /data/db RUN service mongodb start RUN mongod --fork --logpath /var/log/mongodb.log RUN mongo db --eval 'db.createUser({user:"dbuser",pwd:"dbpass",roles:["readWrite","dbAdmin"]})'
The connection fails on the last command:
Error: couldn't connect to server 127.0.0.1:27017 at src/mongo/shell/mongo.js:145 exception: connect failed`.
How can I connect successfully? Should I change the host/IP, and to what, in which commands?
2 Answers
Answers 1
Several things going wrong here. First are the commands you're running:
RUN service mongodb start RUN mongod --fork --logpath /var/log/mongodb.log
Each of these will run to create a layer in docker. And once the command being run returns, the temporary container that was started is stopped and any files changed in the container are captured to make a new layer. There are no persistent processes that last between these commands.
These commands are also running the background version of the startup commands. In docker, you'll find this to be problematic since when you use this as your container's command, you'll find the container dies as soon as the command finishes. Pid 1 on the container has the same role of pid 1 on a linux OS, once it dies, so does everything else.
The second issue I'm seeing is mixing data with your container in the form of initializing the database with the last RUN command. This fails since there's no database running (see above). I'd recommend instead to make an entrypoint that configures the database if one does not already exist, and then use a volume in your docker-compose.yml or on your docker run
commandline to persist data between containers.
If you absolutely must initialize the data as part of your image, then you can try merging the various commands into a single run:
RUN mongod --fork --logpath /var/log/mongodb.log \ && mongo db --eval 'db.createUser({user:"dbuser",pwd:"dbpass",roles:["readWrite","dbAdmin"]})'
Answers 2
I think you misunderstood what Dockerfiles are used for. As Dockerfile reference points out, a
Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.
The whole concept of an image is to derive running container from it which are then filled with data and queried (in case of a database) or are beeing called by an external container / host (in case of an web service) or many other possible usages.
To answer your question I'll assume that:
You want to use a mongo database to store data.
You have some pyhton code which needs to have access to mongo.
You want some initial data in your database.
To do so:
Run a mongo database
docker run --name my-mongo -d mongo
Note: There is no need to write a custom image. Use the official mongo image!
Create a python image which contains your script
a) Write your
Dockerfile
FROM python:3-alpine ADD my_script.py / RUN pip install any-dependency-you-might-need CMD [ "python", "./my_script.py" ]
b) Write your
my_script.py
Insert your application stuff here. It will be executed in the python container. And as mongo will be linked, you can use s.th. like client = MongoClient('mongodb://mongo:27017/')
to get started.
Run your python container with a link to mongo
a) Build it:
docker build -t my-pyhthon-magic .
b) Run it:
docker run -d --name python-magic-container --link my-mongo:mongo my-python-magic
Note: The
--link
here links a running container named my-mongo to be reached internally inmy-python-magic
-container asmongo
. That`s why you can use it in your python script.
I hope this helped you - don't hesitate to ask or modify your question if I misunderstood you.
0 comments:
Post a Comment