November 17, 2014 · virtualization linux containers docker

Running multiple services in Docker container


Docker is amazing in application testing or when we need run something in isolated environment.

But sometimes needed to run daemons (such as sshd or nginx). And there is some problems begin, because in ideology of Docker when process is finished, the container will stop. This is good for single application, we run some code, see results and container stops.
So, is there a solution? Yes, and the answer is supervisord.

It's a python-based tool for controlling processes (including restarting on crash and much more).

In a nutshell is something like init for our container, supervisor has well-documented manual for config files.

Ok, it's a game time!

I'm using Gentoo (3.16.2 kernel) and Docker 1.2.0 in this example

Let's create container for sshd service, and build it using docker build command:

create temporary directory, and write config files here

[sloun@heaven ~ ] cd $(mktemp -d)

in Dockerfile I'll specify what packages needed to install, and what directories needed to create for sshd

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] cat Dockerfile
# vim: set syntax=dockerfile:
#sshd template
FROM debian:stable  
MAINTAINER sloun@roundside  
RUN apt-get update && apt-get -y upgrade \  
&& apt-get -y install openssh-server supervisor \
&& echo 'root:toor' | chpasswd \
&& sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config\
&& mkdir /var/run/supervisor && mkdir /var/run/sshd 
#supervisord config
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf  
EXPOSE 22  
CMD ["/usr/bin/supervisord"]

Now in detail:

The reason to use expose is to make this port available in a container immediately. If not expose port, sshd also will be available, but it will take some time (up to minute!). Read more about this here.

Now, create config file for supervisor (supervisord.conf), simple config for sshd looks like this:

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D  

Ok. We have Dockerfile and supervisord.conf in directory:

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] l
total 8  
-rw-r--r-- 1 sloun sloun 706 Nov 18 03:36 Dockerfile
-rw-r--r-- 1 sloun sloun 166 Nov 18 03:14 supervisord.conf

Time for creating container:

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] docker build -t debian:sshd .

about tag

-t is a tag option to specify local repository for this container

That's all. Start container and expose local port to it:

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] docker run -d -p 127.0.0.1:1030:22 debian:sshd

Sshd now available at 127.1:1030

Mysqld and sshd in one container

Run mysql in that way is also very easy. But there are some pitfalls:

So, my easiest Dockerfile looks like this:

# vim: set syntax=dockerfile:
#sshd-mysqld template
FROM debian:stable  
MAINTAINER sloun@roundside  
RUN apt-get update && apt-get -y upgrade \  
&& apt-get -y install openssh-server mysql-server supervisor \
&& echo 'root:toor' | chpasswd \
&& sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config \
&& sed -i 's/bind-address.\+/bind-address=0.0.0.0/' /etc/mysql/my.cnf \
&& mkdir /var/run/supervisor && mkdir /var/run/sshd
#supervisord config
COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf  
#ports
EXPOSE 22  
EXPOSE 3306  
#stuff for mysql
COPY ./mysql.sh /opt/mysql.sh  
#run supervisord
CMD ["/usr/bin/supervisord"]  

mysql.sh:

#!/usr/bin/env bash
echo "GRANT ALL ON *.* TO root@'%' IDENTIFIED BY 'toor' WITH GRANT OPTION; FLUSH PRIVILEGES" | mysql  

And updated supervisord.conf:

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:mysqld]
command=/usr/bin/mysqld_safe

[program:mysql-configure]
command=/opt/mysql.sh

Build and run.

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] docker build -t debian:sshd_mysqld .
[sloun@heaven /tmp/tmp.Fvl9y73yhl ] docker run -d -p 127.0.0.1:1040:22 -p 127.0.0.1:1041:3306 debian:sshd_mysqld


Look in docker ps:

[sloun@heaven /tmp/tmp.Fvl9y73yhl ] docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                                              NAMES  
9e197bc92b64        debian:sshd_mysqld    "/usr/bin/supervisor   30 minutes ago      Up 30 minutes       127.0.0.1:1040->22/tcp, 127.0.0.1:1041->3306/tcp   insane_franklin  

Now, mysql root login is available at 127.1:4041, and ssh on :4040.

Also, linking containers together is also cool for this!

Thanks to http://txt.fliglio.com/2013/11/creating-a-mysql-docker-container/

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket
Comments powered by Disqus