Skip to main content

Docker: using Monit to manage processes

I know that Docker has been built to run only one process per container (in fact it has no init process like a "normal" operating system), but I like to have an open port to connect to a container to inspect what's going on there.
There's another case for which I need more than one process: one of the web sites I manage is served by a node.js http server proxyed by Apache. To allow for more high availability I start two node processes serving the same site, so that my container needs to have at least two node.js processes running at the same time and listening to two different ports.

I found Monit handy to accomplish this task. The following example shows how to build an image that starts Monit which starts and monitors only the SSH daemon.

As I described in a previous article, I use a setup script to build a new image, so that the Dockerfile is as small as possible.

I'm not showing here the whole Dockerfile, but only the components needed to set up Monit and the SSH daemon. With the following lines the configuration files for Monit are copied into the container:

ADD ./monitrc /home/monitrc
ADD ./sshd.mon /home/sshd.mon

We'll look into these files later.

Then the setup.sh script is run in the container. This script installs Monit, moving its configuration from the /home directory to the final location, then installs SSHD configuring it.

# =====
# Monit
# =====

# install Monit
yum -y -q install http://pkgs.repoforge.org/monit/monit-5.5-1.el6.rf.x86_64.rpm

# move the Monit configuration from the /home directory where the Dockerfile has copied it to the final location
mv /home/monitrc /etc/monit.conf
chmod 600 /etc/monit.conf

# ====
# SSHD
# ====

# install OpenSSH
yum -y -q install openssh-server.x86_64

# this is the directory where the pid file will go
mkdir /var/run/sshd

# create the host keys: the "-A" option is available only starting from CentOS 7
/usr/bin/ssh-keygen -A

# change the root user password
echo 'root:password' | chpasswd

# enable ssh root user login
sed -i -e 's/#PermitRootLogin yes/PermitRootLogin yes/' /etc/ssh/sshd_config

# disable a module that is missing from Docker official CentOS image and prevents SSH to run
sed -i -e 's/\(session \+required \+pam_loginuid.so\)/#\1/' /etc/pam.d/sshd

# move Monit's SSH configuration to the final location
mv /home/sshd.mon /etc/monit.d/

The sshd.mon file describes the SSHD process to Monit telling it what to check and how to start/stop it.

check process sshd with pidfile /var/run/sshd.pid
      start program = "/usr/sbin/sshd"
      stop program = "/usr/bin/pkill sshd"

To add another service to Monit it's sufficient to create another file with ".mon" extension and to put it in the /etc/monit.d directory.

On the other hand the main Monit configuration should be put in /etc/monit.conf. The most important instruction is "set init": this tells Monit to act as the "init" process in a "normal" OS and prevents it from transforming itself into a daemon process.

# number of seconds between checks
set daemon 10

# run as a foreground process
set init

# start the administration interface on port 2812 with user "admin" and password "admin"
set httpd
    port 2812
    allow admin:admin

# include the configuration files for each process to manage 
include /etc/monit.d/*.mon

Running and testing

The command that starts the container is:

monit -l - -c /etc/monit.conf

where "-l -" tells Monit to write its log to the standard output so that "docker logs" can display it.

You run the container with the usual:

docker run -P --rm <IMAGE_NAME>

Then if you look at the running container whith "docker ps" you can see the external port associated with the usual SSH port (22). You should see something like this:

0.0.0.0:49195->22/tcp

To connect to the container you use:

ssh -p 49195 root@localhost

entering the password chosen in the setup script above.
You can also check the status of Monit and the processes it manages by pointing your browser to the host where the container is running and the port specified in monit.conf. The browser will ask you the user/password chosen in the same configuration file.

Comments

Most popular posts

Pairing the Raspberry Pi 3 with your Playstation 3 controller

While setting up the MAME emulator on the Raspberry Pi 3 I decided to experiment with the PS3 controller trying to pair it with the RPi. I found a useful guide here: http://holvin.blogspot.it/2013/11/how-to-setup-raspberry-pi-as-retro.html At section 4 the author describes how to compile sixpair utility, test that everything is working and compile the QtSixA tool. But there are some differences to be noted when working with the Raspberry Pi version 3. First, and most obvious, of all: the RPi 3 has already a Bluetooth device built in, so you don't have to plug a dongle in it, and it's compatible with the PS3 controller. 1. Sixpair The sixpair utility succeeds in coupling with the controller. But to test that it's working I had to test the js1 joystick port, and not the js0 as stated in the guide; so the actual command is: jstest /dev/input/js1 2. QtSixA The QtSixA download link must be changed, because the one shown doesn't compile with the latest

JSON Web Token Tutorial: An Example in Laravel and AngularJS

With the rising popularity of single page applications, mobile applications, and RESTful API services, the way web developers write back-end code has changed significantly. With technologies like AngularJS and BackboneJS, we are no longer spending much time building markup, instead we are building APIs that our front-end applications consume. Our back-end is more about business logic and data, while presentation logic is moved exclusively to the front-end or mobile applications. These changes have led to new ways of implementing authentication in modern applications. Authentication is one of the most important parts of any web application. For decades, cookies and server-based authentication were the easiest solution. However, handling authentication in modern Mobile and Single Page Applications can be tricky, and demand a better approach. The best known solutions to authentication problems for APIs are the OAuth 2.0 and the JSON Web Token (JWT). What is a JSON Web Token? A JSO

Software Release Management For Small Teams

Formalizing The Release Management Process (If There’s Any) In some team configurations, especially ones that are found in startups, there are no DevOps, nor infrastructure engineers, to provide support when releasing a new version of the product. Moreover, unlike large bureaucratic companies with defined formal processes, the CTO or Head of Software Development team in a startup is often not aware of the complexities of the software release management process; a few developers in the company may be aware of the complex details of the process, but not everyone. If this knowledge is not documented thoroughly , I believe it could result in confusion. In this article, I’ll try to provide some tips about how to formalize the release process, particularly from the developer’s point of view. Enter The Software Release Checklist You may be familiar with the idea of a checklist for some operations, as per the Checklist Manifesto , a book by Atul Gawande. I believe a formal release proc