How to Fix “Failed to get D-Bus connection: Operation not permitted” in Dockerized CentOS Services


2 views

When working with CentOS/RHEL-based Docker containers, one common stumbling block occurs when trying to interact with system services. The error typically manifests when running commands like:

systemctl list-units
# Or when trying to start/stop services
service httpd start

Docker containers aren't designed to run full init systems by default. The key issues are:

  • D-Bus isn't running (required for systemd communication)
  • Missing privileges (--privileged flag not set)
  • No PID 1 process management
  • Filesystem namespacing prevents proper service control

Option 1: Run with systemd support (for full service management):

docker run -d --name centos_systemd \
  --privileged \
  --tmpfs /run \
  --tmpfs /run/lock \
  -v /sys/fs/cgroup:/sys/fs/cgroup:ro \
  centos:7 /sbin/init

Option 2: Direct service commands (for single-service containers):

# Instead of systemctl/service commands
/usr/sbin/httpd -DFOREGROUND

Option 3: Alternative container strategies:

# For Docker Compose
services:
  web:
    image: centos:7
    command: /usr/sbin/httpd -DFOREGROUND
    volumes:
      - ./httpd.conf:/etc/httpd/conf/httpd.conf
  • Prefer process-specific commands over systemd in containers
  • Use supervisor or similar tools if managing multiple processes
  • Consider podman (with --systemd flag) for better systemd integration
  • For production, build containers with the specific process as ENTRYPOINT

Check if D-Bus is running:

ps aux | grep dbus

Test basic systemd functionality:

systemd-detect-virt --container

When running systemctl list-units inside a CentOS Docker container, you'll likely encounter:

Failed to get D-Bus connection: Operation not permitted

This occurs because Docker containers don't initialize a full systemd environment by default. The D-Bus system message bus, which systemd requires, isn't available in standard container configurations.

Traditional Linux systems use systemd as PID 1, but Docker containers typically run your process directly as PID 1. Systemd expects certain privileges and access to:

  • The host's cgroups
  • D-Bus socket
  • Full init system capabilities

Here are three approaches to resolve this:

1. Run Container with Systemd Support

Use this docker run command:

docker run -d --name centos-systemd \
--privileged \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
centos:7 /usr/sbin/init

Then exec into the container:

docker exec -it centos-systemd bash

2. Alternative Service Management

For simpler cases, use direct service commands:

# Instead of systemctl start httpd
/usr/sbin/httpd

# Check status
ps aux | grep httpd

3. Dockerfile Configuration

For production deployments, build a proper image:

FROM centos:7
RUN yum install -y systemd; \
yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; \ 
for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /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 -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

After implementing any solution, verify with:

systemctl is-system-running

Should return "running" or "degraded" instead of the D-Bus error.

Using --privileged flag grants extensive permissions. For production environments, consider:

  • Using specific capabilities instead of full privileges
  • Implementing proper container isolation
  • Monitoring systemd processes carefully

For modern container deployments, consider:

  1. Using microservices architecture without systemd
  2. Implementing Kubernetes pods instead of systemd services
  3. Using container-native solutions like Docker Compose