As we know by default Docker container runs without systemd
means the user cannot use systemctl
command. It is because whatever container we create on Docker has not been booted with init. Here we learn how to run Systemd inside the Alamlinux/Rocky Linux/CentOS 8 Docker containers.
Well, the question is why do we get an error whenever we run systemctl
command inside any docker container? What is the reason behind it?
Actually, as per the Docker developers, which they also recommend, one should use a single service inside a container. It means if you are planning to install WordPress using a container then there should be a single container per application. For example Apache + PHP on one container while MySQL on another. Hence, Docker has been developed on this model which means there is no need for Systemd that we find in any standard Linux system to manage and run multiple services in parallel. Therefore, as Docker suggests running multiple containers for different apps, hence the developers disabled this system process manager to improve the container’s isolation and security, that is the reason we get an error whenever we want to use the systemctl
command.
Tip- What is Systemd?
Systemd is a system and session manager (init system) that is responsible for managing all services running on the system over the entire operating time of the computer, from the start-up process to shutdown. Processes are always started in parallel (as far as possible) to keep the boot process as short as possible.
Also, the systemd
is the first process to trigger in a Linux system, that is the reason where we run ps -aux
command on any Linux terminal we see the first process (PID 1) is allocated to the systemd
.
ps -aux
On the other hand, when you run the same command inside a container, you will see the PID (1) means the first process of the system has been allocated to bash.
Hence, this is the reason you will get the error every time you try to start some service inside the Docker container using the systemctl command.
Install or Enable systemd inside Almalinux or Rocky Linux 8 Docker containers
Create a Docker file
There are certain commands that we need to execute before creating a container using either Almalinux or Rocky. Hence instead of running them in a single command, let’s add them in a docker file to create a Docker Image enabled with systemd
.
Create a directory, let’s say ‘sysmd
‘ :
mkdir sysmd
switch to it:
cd sysmd
Create a docker file:
nano Dockerfile
Commands to execute in Docker file to get Systemd
Now, copy-paste the given commands in the Docker file:
Note: Change the almalinux
to rockylinux
, if you want to build a Docker Image to run Rocky Linux.
The given commands in the file will pull the Docker Image (Almalinux or Rocky) and then execute the following command including mounting of Volume and command required to enable Systemd. Also, we will remove some files associated with systemd to enable other services that we don’t require on our command line Docker container.
FROM almalinux ENV container docker RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in ; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); RUN rm -rf /lib/systemd/system/multi-user.target.wants/ \ && rm -rf /etc/systemd/system/.wants/ \ && rm -rf /lib/systemd/system/local-fs.target.wants/ \ && rm -f /lib/systemd/system/sockets.target.wants/udev \ && rm -f /lib/systemd/system/sockets.target.wants/initctl \ && rm -rf /lib/systemd/system/basic.target.wants/ \ && rm -f /lib/systemd/system/anaconda.target.wants/* VOLUME [ “/sys/fs/cgroup” ] CMD ["/usr/sbin/init"]
Save the file by pressing Ctrl+O, hit the Enter key, and then press Ctrl+X to exit the file.
Build Docker Container File with systemd
Now, we fetch and build a Container Image while passing the commands given in the Docker file. For that, there is a command called- docker build
and we use the same.
docker build -t almalinux-md .
Note: You can change almalinux-md with whatever name you want to give your Image. And also don’t forget to add a dot (.) as given in the above command, it guides the build
command to look for Docker File within the directory.
You can see that all the command given in the file has been executed by the docker build
to make a new image with the name you have given to it.
Output:
Sending build context to Docker daemon 2.56kB Step 1/6 : FROM almalinux ---> 4ca63ce1d8a9 Step 2/6 : ENV container docker ---> Running in 57d447426e1a Removing intermediate container 57d447426e1a ---> fa30ff65bd36 Step 3/6 : RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in ; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); ---> Running in bc3b161040e6 Removing intermediate container bc3b161040e6 ---> 6f51cf56580e Step 4/6 : RUN rm -rf /lib/systemd/system/multi-user.target.wants/ && rm -rf /etc/systemd/system/.wants/ && rm -rf /lib/systemd/system/local-fs.target.wants/ && rm -f /lib/systemd/system/sockets.target.wants/udev && rm -f /lib/systemd/system/sockets.target.wants/initctl && rm -rf /lib/systemd/system/basic.target.wants/ && rm -f /lib/systemd/system/anaconda.target.wants/* ---> Running in 082cfe33fc89 Removing intermediate container 082cfe33fc89 ---> 9f8224491315 Step 5/6 : VOLUME [ “/sys/fs/cgroup” ] ---> Running in fe0177b04643 Removing intermediate container fe0177b04643 ---> 212b1b01046b Step 6/6 : CMD ["/usr/sbin/init"] ---> Running in bff7b36d4964 Removing intermediate container bff7b36d4964 ---> 9b8dfd7c1d81 Successfully built 9b8dfd7c1d81 Successfully tagged almalinux-md:latest
Check for created Almalinux or Rocky Linux Image
Now, let’s check whether the Image we have created there to start containers or not:
docker images
Create or Start Docker Container with systemd
We have the Image we have just built, let’s use it to create a container.
docker run -itd --privileged--name h2smedia almalinux-md
h2smedia
is the pretty name that we want to give to our container whereas almalinux-md
is the name of the image we have created, replace it with yours.
Warning: Here we are running the container with a privileged flag, this will give extra power to containers, in simple words- the container will have rights or roots privilege to the host machine. Such containers, we usually use when we want to give direct hardware access (of the host) or want to run a container inside a container. So, it is recommended not to use such containers for commercial or enterprise usage where outside users accessing some services. Make it for development or local purposes only. That is the reason we ran the above command with this flag so that we can have the Systemd facility or init in our container.
Switch to Container Bash
Now, let’s access the container command line to check whether we can run systemctl
command or not.
Now, you have the Docker Image with Systemd and this will allow you to create as many as containers you want for developing or testing local applications.
Other tutorials:
• How to install and setup Docker Container on AlmaLinux 8
• How to create a Systemd service unit file in Linux
• Analyze Linux system boot time with Systemd