Bookmark this page

Managing Containers as Services

Objectives

After completing this section, you should be able to start, stop, and check the status of a container as a systemd service.

Starting Containers Automatically with the Server

When you deploy services such as databases or web servers as containers, you usually want those containers to start automatically with the server.

By creating systemd user unit files for your rootless containers, you can manage them with systemctl commands, similar to regular services. By enabling those services, you ensure that the associated containers start when the host machine starts. If your container runs in "rootless" mode, you can manage these services from a non-privileged user account for increased security.

For more sophisticated scaling and orchestration of many container-based applications and services, you can use an enterprise orchestration platform based on Kubernetes, such as Red Hat OpenShift Container Platform.

Running Systemd Services as a Regular User

In addition to managing system services, systemd can also manage user services. With systemd user services, users can create unit files for their own services and manage those services with systemctl commands, without requiring root access.

When you enable a user service as a non-root user, that service automatically starts when you open your first session through the text or graphical consoles or using SSH. The service stops when you close your last session. This behavior differs from the system services, which start when the system starts and stop when the system shuts down.

However, you can change this default behavior and force your enabled services to start with the server and stop during the shutdown by running the loginctl enable-linger command. To revert the operation, use the loginctl disable-linger command. To view the current status, use the loginctl show-user username command with your user name as parameter.

[user@host ~]$ loginctl enable-linger
[user@host ~]$ loginctl show-user user
...output omitted...
Linger=yes
[user@host ~]$ loginctl disable-linger
[user@host ~]$ loginctl show-user user
...output omitted...
Linger=no

Creating and Managing Systemd User Services

To define systemd user services, create the ~/.config/systemd/user/ directory to store your unit files. The syntax of those files is the same as the system unit files. For more details, review the systemd.unit(5) and systemd.service(5) man pages.

To control your new user services, use the systemctl command with the --user option. The following example lists the unit files in the ~/.config/systemd/user/ directory, forces systemd to reload its configuration, and then enables and starts the myapp user service.

[user@host ~]$ ls ~/.config/systemd/user/
myapp.service
[user@host ~]$ systemctl --user daemon-reload
[user@host ~]$ systemctl --user enable myapp.service
[user@host ~]$ systemctl --user start myapp.service

Note

To use systemctl --user commands, you must log in at the console or directly through SSH. Using the sudo or su commands does not work.

The systemctl command interacts with a per user systemd --user process. The system only starts that process when the user logs in for the first time from the console or SSH.

The following table summarizes the differences between systemd system and user services.

Table 16.2. Comparing System and User Services

Storing custom unit files System services /etc/systemd/system/unit.service
User services ~/.config/systemd/user/unit.service
Reloading unit files System services
# systemctl daemon-reload
User services
$ systemctl --user daemon-reload
Starting and stopping a service System services
# systemctl start UNIT
# systemctl stop UNIT
User services
$ systemctl --user start UNIT
$ systemctl --user stop UNIT
Starting a service when the machine starts System services
# systemctl enable UNIT
User services
$ loginctl enable-linger
$ systemctl --user enable UNIT

Managing Containers Using Systemd Services

If you have a single container host running a small number of containers, then you can set up user-based systemd unit files and configure them to start the containers automatically with the server. This is a simple approach, mainly useful for very basic and small deployments that do not need to scale. For more practical production installations, consider using Red Hat OpenShift Container Platform, which will be discussed briefly at the end of this section.

Creating a Dedicated User Account to Run Containers

To simplify the management of the rootless containers, you can create a dedicated user account that you use for all your containers. This way, you can manage them from a single user account.

Note

The account that you create to group all your containers must be a regular user account. When you create an account with useradd, the command reserves a range of user IDs for the user's containers in the /etc/subuid file. However, when you create a system account, with the --system (or -r) option of useradd, the command does not reserve a range. As a consequence, you cannot start rootless containers with system accounts.

Creating the Systemd Unit File

From an existing container, the podman command can generate the systemd unit file for you. The following example uses the podman generate systemd command to create the unit file for the existing web container:

[user@host ~]$ cd  ~/.config/systemd/user/
[user@host user]$ podman generate systemd --name web --files --new
/home/user/.config/systemd/user/container-web.service

The podman generate systemd command uses a container as a model to create the configuration file. After the file is created, you must delete the container because systemd expects the container to be absent initially.

The podman generate systemd command accepts the following options:

--name container_name

The --name option specifies the name of an existing container to use as a model to generate the unit file. Podman also uses that name to build the name of the unit file: container-container_name.service.

--files

The --files option instructs Podman to generates the unit file in the current directory. Without the option, Podman displays the file in its standard output.

--new

The --new option instructs Podman to configure the systemd service to create the container when the service starts and delete it when the service stops. In this mode, the container is ephemeral, and you usually need persistent storage to preserve the data. Without the --new option, Podman configures the service to start and stop the existing container without deleting it.

The following example shows the start and stop directives in the unit file when you run the podman generate systemd command with the --new option:

[user@host ~]$ podman run -d --name web -v /home/user/www:/var/www:Z registry.redhat.io/rhel8/httpd-24:1-105
[user@host ~]$ podman generate systemd --name web --new
...output omitted...
ExecStart=/usr/bin/podman run --conmon-pidfile %t/%n-pid --cidfile %t/%n-cid --cgroups=no-conmon -d --name web -v /home/user/webcontent:/var/www:Z registry.redhat.io/rhel8/httpd-24:1-105 1
ExecStop=/usr/bin/podman stop --ignore --cidfile %t/%n-cid -t 10 2
ExecStopPost=/usr/bin/podman rm --ignore -f --cidfile %t/%n-cid 3
...output omitted...

1

On start, systemd executes the podman run command to create and then start a new container.

2

On stop, systemd executes the podman stop command to stop the container.

3

After systemd has stopped the container, systemd removes it using the podman rm command.

In contrast, the following example shows the start and stop directives when you run the podman generate systemd command without the --new option:

[user@host ~]$ podman run -d --name web -v /home/user/www:/var/www:Z registry.redhat.io/rhel8/httpd-24:1-105
[user@host ~]$ podman generate systemd --name web
...output omitted...
ExecStart=/usr/bin/podman start web 1
ExecStop=/usr/bin/podman stop -t 10 web 2
...output omitted...

1

On start, systemd executes the podman start command to start the existing container.

2

On stop, systemd executes the podman stop command to stop the container. Notice that systemd does not delete the container.

Starting and Stopping Containers Using Systemd

Use the systemctl command to control your containers.

  • Starting the container:

    [user@host ~]$ systemctl --user start container-web
  • Stopping the container:

    [user@host ~]$ systemctl --user stop container-web
  • Getting the status of the container:

    [user@host ~]$ systemctl --user status container-web

Important

Containers managed with the systemctl command are controlled by systemd. systemd monitors container status and restarts them if they fail.

Do not use the podman command to start or stop these containers. Doing so may interfere with systemd monitoring.

Configuring Containers to Start When the Host Machine Starts

By default, enabled systemd user services start when a user opens the first session, and stop when the user closes the last session. For the user services to start automatically with the server, run the loginctl enable-linger command:

[user@host ~]$ loginctl enable-linger

To enable a container to start when the host machine starts, use the systemctl command:

[user@host ~]$ systemctl --user enable container-web

To disable the start of a container when the host machine starts, use the systemctl command with the disable option:

[user@host ~]$ systemctl --user disable container-web

Managing Containers Running as Root with Systemd

You can also configure containers that you want to run as root to be managed with Systemd unit files. One advantage of this approach is that you can configure those unit files to work exactly like normal system unit files, rather than as a particular user.

The procedure to set these up is similar to the one previously outlined for rootless containers, except:

  • You do not need to set up a dedicated user.

  • When you create the unit file with podman generate systemd, do it in the /etc/systemd/system directory instead of in the ~/.config/systemd/user directory.

  • When configuring the container's service with systemctl, you will not use the --user option.

  • You do not need to run loginctl enable-linger as root.

For a demonstration, see the YouTube video from the Red Hat Videos channel listed in the References at the end of this section.

Orchestrating Containers at Scale

In this chapter, you learned how to manually configure and manage containers from the command line on a single host, and how to configure Systemd so that containers start automatically with the server. This is useful at a very small scale and to learn more about containers.

However, in practice most enterprise deployments need more. The introduction to this chapter mentioned that Kubernetes is generally used to manage complex applications that consist of multiple cooperating containers. Red Hat OpenShift is a Kubernetes platform that adds a web-based user interface, monitoring, the ability to run containers anywhere in a cluster of container hosts, autoscaling, logging and auditing, and much more.

Discussing these tools is beyond the scope of this course. If you want to learn more, Red Hat Training offers other courses, starting with the free technical overview course Deploying Containerized Applications (DO080) and continuing with Red Hat OpenShift I: Containers & Kubernetes (DO180). For more information, visit https://learn.spidernet.pl/training.

You can also learn more about Kubernetes and Red Hat OpenShift from https://www.openshift.com. A number of resources are available there, including ways to try out OpenShift for yourself using tools like CodeReady Containers. See https://www.openshift.com/try for more information.

References

loginctl(1), systemd.unit(5), systemd.service(5), subuid(5), and podman-generate-systemd(1) man pages

Improved systemd integration with Podman 2.0

Managing Containers in Podman with Systemd Unit Files

What is OpenShift

Get Started with OpenShift

For more information, refer to the Running Containers as Systemd Services with Podman chapter in the Red Hat Enterprise Linux 8 Building, Running, and Managing Containers Guide at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/building_running_and_managing_containers/index#using-systemd-with-containers_building-running-and-managing-containers

Revision: rh199-8.2-3beeb12