The following documentation from the Docker website shows how to implement an SSH service in a docker container. It should be easily adaptable for your service:
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.
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
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:
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
I add the following code to /root/.bashrc to run the code only once,
Please commit the container to the image before run this script, otherwise the 'docker_services' file will be created in the images and no service will be run.
if [ ! -e /var/run/docker_services ]; then
echo "Starting services"
service mysql start
service ssh start
service nginx start
touch /var/run/docker_services
fi
Side note:
In my opinion reasonable is to start only cron service leaving container as clean as possible then just modify crontab or cron.hourly, .daily etc... with corresponding checkup/monitoring scripts. Reason is You rely only on one daemon and in case of changes it is easier with ansible or puppet to redistribute cron scripts instead of track services that start at boot.