Running systemctl in a Docker Container Using systemd

This guide explains how to run systemctl within a Docker container by using a systemd-based Docker image. This approach is ideal for scenarios where you need to manage services inside a container in a way that resembles a traditional Linux system.

Prerequisites

  • Docker installed on your system

  • Familiarity with basic Docker commands

Step 1: Choose a Base Image with systemd

Choose a base image that includes systemd support. Some commonly used images are:

  • centos/systemd

  • ubuntu:systemd

These images come with systemd pre-installed and configured for use in containers.

Step 2: Write a Dockerfile

Create a Dockerfile that uses the chosen base image and includes any necessary setup, such as installing packages or copying configuration files.

Example Dockerfile:

FROM centos/systemd

# Install necessary packages
RUN yum -y install httpd && yum clean all

# Enable and start the httpd service
RUN systemctl enable httpd

CMD ["/usr/sbin/init"]

This example installs the Apache HTTP server and enables it to start with systemd.

Step 3: Build the Docker Image

Build the Docker image from your Dockerfile:

docker build -t my-systemd-container .

Step 4: Run the Container with Privileges and Mounted cgroups

To enable systemd to function correctly within the container, run the container with --privileged mode and mount the cgroup file system.

docker run -d --privileged --name=mycontainer -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run --tmpfs /run -v /run/lock --tmpfs /run/lock my-systemd-container
  • --privileged: Grants the container permissions needed to interact with systemd.

  • -v /sys/fs/cgroup:/sys/fs/cgroup:ro: Mounts cgroup as read-only, which is required for systemd to manage services.

  • -v /run --tmpfs /run and -v /run/lock --tmpfs /run/lock: Mounts /run and /run/lock as temporary file systems to provide the required system directories for systemd.

Step 5: Access the Container and Use systemctl

After starting the container, you can interact with it using systemctl commands to manage services.

docker exec -it mycontainer /bin/bash

Once inside the container, use systemctl to check the status of services or to start/stop services as needed:

# Check the status of the httpd service
systemctl status httpd

# Start or stop services
systemctl start httpd
systemctl stop httpd

Step 6: Stop and Clean Up the Container

To stop and remove the container:

docker stop mycontainer
docker rm mycontainer

Additional Notes

  • Running systemd inside a Docker container is generally discouraged unless absolutely necessary, as it increases the complexity of container management.

  • Consider alternative approaches like supervisord or separate containers for each service if you don't specifically need systemctl.

This setup can be useful for development, testing, or specific applications that rely on systemd within containers.