I'm setting up a simple image: one that holds Riak (a NoSQL database). The image starts the Riak service with riak start
as a CMD. Now, if I run it as a daemon with docker run -d quintenk/riak-dev
, it does start the Riak process (I can see that in the logs). However, it closes automatically after a few seconds. If I run it using docker run -i -t quintenk/riak-dev /bin/bash
the riak process is not started (UPDATE: see answers for an explanation for this). In fact, no services are running at all. I can start it manually using the terminal, but I would like Riak to start automatically. I figure this behavior would occur for other services as well, Riak is just an example.
So, running/restarting the container should automatically start Riak. What is the correct approach of setting this up?
For reference, here is the Dockerfile with which the image can be created (UPDATE: altered using the chosen answer):
FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y openssh-server curl
RUN curl http://apt.basho.com/gpg/basho.apt.key | apt-key add -
RUN bash -c "echo deb http://apt.basho.com precise main > /etc/apt/sources.list.d/basho.list"
RUN apt-get update
RUN apt-get -y install riak
RUN perl -p -i -e 's/(?<=\{http,\s\[\s\{")127\.0\.0\.1/0.0.0.0/g' /etc/riak/app.config
EXPOSE 8098
CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1
EDIT: -f changed to -F in CMD in accordance to sesm his remark
MY OWN ANSWER
After working with Docker for some time I picked up the habit of using supervisord to tun my processes. If you would like example code for that, check out https://github.com/Krijger/docker-cookbooks. I use my supervisor image as a base for all my other images. I blogged on using supervisor here.
To keep docker containers running, you need to keep a process active in the foreground.
So you could probably replace that last line in your Dockerfile with
Or even
Note that you can't have multiple lines of CMD statements, only the last one gets run.
Using tail to keep container alive is a hack. Also, note, that with
-f
option container will terminate when log rotation happens (this can be avoided by using-F
instead).A better solution is to use supervisor. Take a look at this tutorial about running Riak in a Docker container.
It sounds like you only want to be able to monitor the log when you attach to the container. My use case is a little different in that I want commands started automatically, but I want to be able to attach to the container and be in a bash shell. I was able to solve both of our problems as follows:
In the image/container, add the commands you want automatically started to the end of the
/etc/bash.bashrc
file.In your case just add the line
/bin/riak start && tail -F /var/log/riak/erlang.log.1
, or put/bin/riak start
andtail -F /var/log/riak/erlang.log.1
on separate lines depending on the functionality desired.Now commit your changes to your container, and run it again with:
docker run -i -t quintenk/riak-dev /bin/bash
. You'll find the commands you put in the bashrc are already running as you attach.I use a simple trick whenever I start building a new docker container. To keep it alive, I use a ping in the entrypoint script.
So in the Dockerfile, when using debian, for instance, I make sure I can ping. This is btw, always nice, to check what is accessible from within the container.
And in the entrypoint.sh file
I use this instead of
CMD bash
, as I always wind up using a startup file.Because I want a clean way to have the process exit later I make the last command a call to the shell's
read
which causes that process to block until I later attach to it and hit enter.as you can see the container exits after you attach to it and unblock the read. You can of course use a more sophisticated script than
read -p
if you need to do other clean up, such as stopping services and saving logs etc.The explanation for:
is as follows. Using CMD in the Dockerfile is actually the same functionality as starting the container using
docker run {image} {command}
. As Gigablah remarked only the last CMD is used, so the one written in the Dockerfile is overwritten in this case.By using
CMD /bin/riak start && tail -f /var/log/riak/erlang.log.1
in the Buildfile, you can start the container as a background process usingdocker run -d {image}
, which works like a charm.