Overview & Root Cause Summary: The error
System has not been booted with systemd as init system (PID 1). Can't operate. Failed to connect to bus: Host is downoccurs when runningsystemctlcommands in environments where systemd is not running as Process ID 1 (PID 1). This is standard behavior in typical Docker containers, unconfigured WSL2 instances, and chroot environments.
Understanding the Root Causes
- Standard Docker Container Architecture: Docker containers are designed to run an isolated application process (e.g., Node.js, Python, or Nginx) as PID 1, rather than a full system init daemon like systemd.
- WSL2 Default Configuration: Windows Subsystem for Linux (WSL2) originally booted with Microsoft’s custom init tool. Unless explicitly enabled in
/etc/wsl.conf, systemd and the D-Bus daemon remain inactive. - Chroot & Minimal Containers: Embedded, rescue, or minimal Alpine/Debian chroot filesystems mount without initialized cgroups or active D-Bus control sockets.
Step 1: Quick Fix for WSL2 (Enable systemd in wsl.conf)
If you are encountering this error inside Windows Subsystem for Linux (WSL2), enable native systemd support in your distribution.
# 1. Edit the WSL configuration file inside your Linux terminal:
sudo nano /etc/wsl.conf
# 2. Add the following section to enable systemd:
[boot]
systemd=true
# 3. Save the file (Ctrl+O, Enter, Ctrl+X).
# 4. Open PowerShell on Windows and restart WSL:
wsl --shutdown
# 5. Reopen your Linux distribution in terminal and verify:
ps -p 1 -o comm=
# Expected output: systemd
Step 2: Workarounds for Docker Containers (SysVinit & Direct Execution)
Inside standard Docker containers, avoid using systemctl. Instead, use legacy service managers or invoke the binary directly.
# Approach A: Use SysVinit / service commands:
sudo service nginx start
sudo service mysql status
sudo service cron start
# Approach B: Run the service directly in the foreground (Recommended for Dockerfile CMD):
# Instead of: CMD ["systemctl", "start", "nginx"]
CMD ["nginx", "-g", "daemon off;"]
# Approach C: For background helper scripts:
/etc/init.d/ssh start
Step 3: Running a Full systemd Environment in Docker (Advanced)
If your workload strictly requires systemd (such as testing Ansible playbooks or multi-daemon packages), launch a privileged container configured for systemd.
# Run an Ubuntu container with systemd and mounted cgroups:
docker run -d \
--name systemd-container \
--privileged \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw \
--cgroupns=host \
ubuntu:22.04 /sbin/init
# Exec into the running systemd container:
docker exec -it systemd-container bash
# Test systemctl commands inside the container:
systemctl status
Verification & Testing Steps
Confirm whether systemd is managing PID 1 and verify D-Bus communication.
# 1. Verify that PID 1 is systemd:
ps -p 1 -o comm=
# 2. Check systemd operational state:
systemctl is-system-running
# 3. Test starting a service:
sudo systemctl status ssh || sudo service ssh status
Summary Comparison Table
| Environment | Recommended Solution | PID 1 Process | Implementation Complexity |
|---|---|---|---|
| WSL2 (Windows) | Set systemd=true in /etc/wsl.conf | systemd | Low (< 2 mins) |
| Standard Docker Container | Use service or run binary in foreground | Application Binary / Bash | Very Low |
| Privileged Docker Container | Mount /sys/fs/cgroup and boot /sbin/init | systemd | Medium |
| Chroot / Rescue Shell | Use service name start or direct binary | Host Shell | Low |
Leave a Reply