Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically start a service when running a docker container?

Tags:

docker

People also ask

How do containers start automatically?

Docker provides restart policies to control whether your containers start automatically when they exit, or when Docker restarts. Restart policies ensure that linked containers are started in the correct order. Docker recommends that you use restart policies, and avoid using process managers to start containers.

How do I start a single service from a docker file?

To start (up), stop, restart or build a single service (container) using the Docker Compose, simply specify the name of the service against which to run the corresponding docker-compose command.


First, there is a problem in your Dockerfile:

RUN service mysql restart && /tmp/setup.sh

Docker images do not save running processes. Therefore, your RUN command executes only during docker build phase and stops after the build is completed. Instead, you need to specify the command when the container is started using the CMD or ENTRYPOINT commands like below:

CMD mysql start

Secondly, the docker container needs a process (last command) to keep running, otherwise the container will exit/stop. Therefore, the normal service mysql start command cannot be used directly in the Dockerfile.

Solution

There are three typical ways to keep the process running:

  • Using service command and append non-end command after that like tail -F

    CMD service mysql start && tail -F /var/log/mysql/error.log
    

This is often preferred when you have a single service running as it makes the outputted log accessible to docker.

  • Or use foreground command to do this

    CMD /usr/bin/mysqld_safe
    

This works only if there is a script like mysqld_safe.

  • Or wrap your scripts into start.sh and put this in end

    CMD /start.sh
    

This is best if the command must perform a series of steps, again, /start.sh should stay running.

Note

For the beginner using supervisord is not recommended. Honestly, it is overkill. It is much better to use single service / single command for the container.

BTW: please check https://registry.hub.docker.com for existing mysql docker images for reference


In your Dockerfile, add at the last line

ENTRYPOINT service ssh restart && bash

It works for me

And this is the result:

root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu
 * Restarting OpenBSD Secure Shell server sshd   [ OK ]                                                                      
root@dccc354e422e:~# service ssh status
 * sshd is running

Simple! Add at the end of dockerfile:

ENTRYPOINT service mysql start && /bin/bash

There's another way to do it that I've always found to be more readable.

Say that you want to start rabbitmq and mongodb when you run it then your CMD would look something like this:

CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start

Since you can have only one CMD per Dockerfile the trick is to concatenate all instructions with && and then use \ for each command to start a new line.

If you end up adding to many of those I suggest you put all your commands in a script file and start it like @larry-cai suggested:

CMD /start.sh

In my case, I have a PHP web application being served by Apache2 within the docker container that connects to a MYSQL backend database. Larry Cai's solution worked with minor modifications. I created a entrypoint.sh file within which I am managing my services. I think creating an entrypoint.sh when you have more than one command to execute when your container starts up is a cleaner way to bootstrap docker.

#!/bin/sh

set -e

echo "Starting the mysql daemon"
service mysql start

echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite

a2enmod headers
service apache2 restart

a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload

if [ -z "$1" ]
then
    exec "/usr/sbin/apache2 -D -foreground"
else
    exec "$1"
fi