4

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,

DevHugo
  • 129
  • 1
  • 1
  • 12

3 Answers3

3

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"]
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thank you, that working for my use case. But one question for my personal knowledge : Why in the official CentOS image, we can found this : https://github.com/docker-library/docs/tree/master/centos#systemd-integration to use `systemctl`? According that you said above. – DevHugo Oct 10 '18 at 12:37
1

The systemctl tool on CentOS 7 and later will not do anything itself, it will simply talk to the systemd daemon on PID 1. It uses a dbus connection for that - and that's the cause of the error that you see.

If you really want to use the classic sbin/init then you should install the initscripts package before. If you want to keep more compatibility with installation instructions for a real system then you could als replace systemctl by a tool that works without a systemd daemon, e.g. the docker-systemctl-replacement, which one also put as CMD to serve as the init-daemon that runs all enabled services in correct order.

Guido U. Draheim
  • 3,038
  • 1
  • 20
  • 19
  • I have few queries. How to replace systemd with docker-systemctl-replacement ? (Is there any specific steps need to follow) – Cracken Jun 10 '19 at 11:46
  • install python in the container and overwrite /usr/bin/systemctl. Replace the CMD with /usr/bin/systemctl to have it run the applications in the container - that are enabled by 'systemctl enable xxx.service'. – Guido U. Draheim Jun 10 '19 at 12:41
0

It's useful to run a real init system in docker. It takes all the work out of dockerization, logging works properly and CMD can always be just /sbin/init. I had the same problem as you, systemctl didn't work and the service didn't seem to start at all when following centos' docs.

Try ignoring the advice about deleting all system units before starting the container, as in https://github.com/dholth/vagrant-docker

I wonder which are required?

joeforker
  • 40,459
  • 37
  • 151
  • 246