Managing Containers with Systemd
To reduce the need for manual intervention, use systemd to manage container-based applications on a health check.

Containers are inherently ephemeral, making them more difficult to manage than traditional programmes operating on virtual or bare metal servers. Container monitoring, on the other hand, is a critical capability for applications based on current microservices architectures in order to achieve maximum performance.
Containerized applications frequently necessitate monitoring. Performing health-checks is one technique to keep these containers up and running at all times. The usage of the curl
command to verify if the application within the container is still up and running is one of the approaches I’ve come across for doing health-checks. The cronjob
utility is used to perform curl commands on the container application at a periodic basis. If the container is not in a running state, a configuration management tool like Ansible can be used to start/restart it. Although this method does not need direct human intervention, it does not seem to have a mechanism for logging
the event i.e. reason for downtime of the application/container. Therefore, it is not the best option for enhancing the container’s self-healing capabilities.
Instead, we make use of the systemd
utility of Linux which is ubiquitous across most of the Linux distributions. The systemd utility makes it easy to dynamically start/restart/stop configuration files for each deamon.
In this blog, we will:
- Create an Ansible role.
- Define the required variables.
- Create the service file usign a Jinja2 template
- Manage unit files within the containers using a playbook
With the aid of systemd, we’ll start an apache container and control its daemon. The Jinja2 templates
are used to construct the unit file. We save the template files in the /usr/lib/systemd/system/
directory after they’ve been created. We can then use thesystemd
ansible module to administer the deamon once the files have been stored in the correct location with the required permissions.
Create an Ansible role
cd roles
mkdir -p apache/{defaults,tasks,templates,handlers}
Define the required variables
---
apache_image: "httpd"
apache_image_tag: "latest"
Create the service file usign a Jinja2 template
[Unit]
Description=run apache container
After=network.target docker.service
Requires=docker.service
[Service]
ExecStartPre=-/usr/bin/docker stop apache
ExecStartPre=-/usr/bin/docker rm apache
ExecStartPre=/usr/bin/docker pull {{ apache_image }}:{{ apache_image_tag }}
ExecStart=/usr/bin/docker run \
--port='8080:8080' \
--name=apache \
--volume={{ apache_data_dir }}:{{ apache_data_container_dir }}:ro \
--restart=always \
--log-driver=journald \
{{ apache_image }}:{{ apache_image_tag }}
Restart=always
[Install]
WantedBy=multi-user.target
Manage unit files within the containers using a playbook
/roles/apache/handlers/main.yml
---
- name: restart container-apache
systemd:
name: container-apache.service
daemon_reload: yes
state: restarted
/roles/apache/tasks/main.yml
---
- name: set selinux boolean value
seboolean:
name: container_manage_cgroup
state: yes
persistent: yes
- name: create the apache container unit file
template:
src: container-apache.service.j2
dest: /usr/lib/systemd/system/container-apache.service
owner: root
mode: 0660
notify: restart container-apache
- name: link and enable container-apacahe
systemd:
name: container-apache
enabled: yes
- name: run apache container
systemd:
name: container-apache
state: started