Running Multiple Services in a Docker Container via Supervisord at runtime

Have you ever faced this scenario where you want to run two or more lightweight services or multiple executables within the same container when the image starts running?

Although Docker provides a Docker-compose tool for building and running multi-services applications in multiple containers. Docker-compose requires a YAML file to configure your multiple services. But sometimes we want to run two or more lightweight services inside the same container.

While working with Docker on a use case wherein I was supposed to implement two processes in a single docker container. Docker always had a limitation that only one CMD parameter can be provided in the Dockerfile as only one process can be run in the foreground. This use case included running Httpd and SSH on a single docker container that by far seem to be achievable only by passing shell script in CMD parameter of Dockerfile. After a rigorous search on the internet, I found this utility Supervisor by virtue of which we can run more than one process in a Docker container without having to worry about single CMD parameter or using shell scripts.

In this article I will illustrate how you can run services like SSHd and HTTPd inside a single container at start time with Cent OS as the base image by using the SupervisorD service.

Why do we need Supervisord ?

Now, one of the problems we will face deploying multiple services like SSH ,Http is: How to control these services ? as we do not have init scripts or systemd available inside the containers and we do not even want them. Hence we will need some kind of mechanism to start, stop and monitor status of our services.

SupervisorD is a process control system, designed to monitor and control processes. It does not aim to replace init, instead it encapsulates processes inside its own framework, and can start them at boot time, just like we want.The Supervisor is a process control and monitoring tool that can be used to control multiple processes on UNIX-like OS.

Although SupervisorD adds another layer of complexity ,it is indeed a very simple and useful way to manage multiple services .

According to some senior Docker Captains like Bret Fisher , this method is the most successful in deployment of highly scaled Web Applications running in production of the AWS cloud.

In order to install Supervisord almost all the Linux distributions have supervisor (or supervisord) in their default package repository – it just needs to be installed. SupervisorD is a python module. It can be installed using easy_install, which is a part of setuptools, which itself is an extension of the Python distutils package. Yes, it does get complicated quite at this point. Luckily, most Linux distributions ship with easy_install, including CentOS, which we will create today to make a Linux Distribution image.

Lets get started with the Dockerfile , below is the step by step screenshots of the process ,for code : https://github.com/aniforverizon/Docker_SSH_httpd_supervisor.git

You can see that I am taking CentOS as the base image, having a root as the user and installing standard packages for SSHd ,Supervisord and HTTPd as a service : Openssh ,Python setup tools ,network tools and httpd.Also adding the ssh configurations file consisting of passwords ,usernames and policies.

We will run Supervisord in the foreground and supervisord.conf file that has to be passed in the Dockerfile in which we can tell multiple processes to be run inside Docker container.

Building the image

We are building the image for the same, lets observe the layer by layer build .

installation of binaries
openssh and ftp
python and supervisord install on container
httpd install on the container
SSH configurations files mounted on the container
Supervisord running via Docker CMD and SSH port 22 exposed

Finally when we spawn the container , we see httpd and sshd coming up on runtime:

both services coming up on runtime in the logs

When we look at all the ports and services open via : “ss -tln” command in Linux we can see some ports coming up:

Running commands to see ports open in container

When I say that SSHd service is up and running on the container at runtime along with spawn & boot, then we need to confirm this by taking ssh access to this container, lets see what port is up and how to take access:

getting the port allocated and later getting access

We can get the SSH access and get started by using it :

To see the configurations sent in Supervisord for SSH service:

bootstrap config for ssh

There are supervisord.conf standard configurations that have to be made, this is what the file looks like:

Supervisord.conf file

What are we doing here? Each square bracket pair defines a section. For supervisord itself, we define that it should start in the foreground rather than daemonize itself, which would mean becoming a background service.

For the program named sshd, we execute the relevant command, essentially running SSHD in the background. For the program named httpd, we start the server in the foreground, in a separate shell. There are many other options available, but at the moment, this is the bare minimum we need to get underway with supervisord.

Also the file required for running the SSH service on runtime.

I took SSHD service in this example because its a popular service and wanted to demonstrate how containers can be accessed via SSH, but ideally it is not a good practice to run SSHd inside your containers , for further reference : follow this link .

For accessing code of this article click on this.

For any further Queries or anything related to Blockchain or DevOps or specialized Docker queries you can DM me on Linkedin or instagram id=acanubhav94.

Linux-DevOps Geek,Army Brat,Blockchain Evangelist ,Statistics & Data Nerd ,Solutions architect, passionate hands on instructor.High on Athletics,Travel,Growth !