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:
- Using microservices architecture without systemd
- Implementing Kubernetes pods instead of systemd services
- Using container-native solutions like Docker Compose