Search code examples
dockerdockerfilecentos7systemd

Docker CentOS systemctl not permitted


I trying to build a CentOS image with systemctl command. But each time when I build it. I obtain this error :

Step 5/7 : RUN systemctl enable syslog-ng ; systemctl start syslog-ng
 ---> Running in 8f5a357895e7
Failed to get D-Bus connection: Operation not permitted
The command '/bin/sh -c systemctl enable syslog-ng ; systemctl start syslog-ng' returned a non-zero code: 1

My Dockerfile :

FROM centos_systemctl:latest 

RUN yum -y update
RUN yum -y install epel-release ; \
    yum -y install vim ; \
    yum -y install wget ; \
    yum -y install rsync ; \
    yum -y groupinstall "Development tools"
# Install syslog-ng 3.14
RUN cd /etc/yum.repos.d/ ; \
    wget https://copr.fedorainfracloud.org/coprs/czanik/syslog-ng314/repo/epel-7/czanik-syslog-ng314-epel-7.repo ; \
    yum -y install syslog-ng
RUN systemctl enable syslog-ng ; systemctl start syslog-ng
RUN yum -y remove rsyslog
# COPY config syslog-ng
CMD ["/usr/sbin/init"]

centos_systemctl:latest according to this : https://github.com/docker-library/docs/tree/master/centos#systemd-integration

Someone know what I do wrong ?

Thanks,


Solution

  • You should assume systemd and systemctl just don't work in Docker, and find another approach to whatever your higher-level goals are. Best practices are to run one service and one service only in a Docker container, and to use multiple containers if you need multiple coordinating services; if you really must run multiple things in the same container then supervisord is a common process manager.

    The biggest problem with systemd in Docker is that it by default wants to control a lot of things. Look at the graphic on the systemd home page: it wants to do a bunch of kernel-level setup, manage filesystems, and launch several services, all of which have already been done on the host and are unnecessary in a Docker container. The "easy" way to run systemd in Docker involves giving it permission to reconfigure your host; the link you provide has a "hard" way that involves deleting most of its control files.

    In a Dockerfile context there's also a problem that each RUN line starts from a clean slate with no processes running at all. So your systemctl start ... command doesn't work because the systemd init isn't running; and even if it did, when that RUN command finished, the process would go away and the service wouldn't be running on the next line.

    You might be able to find a prebuilt syslog-ng image by typing "syslog" into the search box on https://hub.docker.com, which would dodge this issue. It also might work to install syslog-ng on a CentOS base as you do, but skip systemd entirely and just run the service as the primary command the image runs

    CMD ["syslog-ng", "-F"]