System has not been booted with systemd as init system (PID 1). Can't operate.
followed by Failed to connect to bus: Host is down is what
systemctl prints inside a Docker container. A container does not boot an
operating system, so there is no systemd to talk to. Do not try to start services; run the
program itself in the foreground as the container's main process.
For a quick test inside a running container, service nginx start uses the old
init script and works. For an image, make the server the CMD, for example
CMD ["nginx", "-g", "daemon off;"], and let Docker start, stop and restart it.
The error
docker exec fix8-bld-sysd systemctl start nginx
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
systemctl status nginx printed the same two lines, and both exited with code 1.
The systemd package (255.4-1ubuntu8.18) was installed; the command exists, it just has
nothing to connect to.
Why it happens
systemctl is only a client. It sends requests over D-Bus to systemd, which on a
normal machine is process 1 and supervises every service. In a container, process 1 is
whatever the image's CMD or ENTRYPOINT says. In the test container
it was sleep 900; reading /proc/1/cmdline showed exactly that. No
systemd, no bus, so systemctl refuses to operate.
This is by design: a container is meant to run one main process, and Docker plays the role
of the service manager. Its restart policy, docker logs and health checks
replace what systemd units do on a server. Running full systemd inside a container is
possible with extra privileges and mounts, but it is rarely what you want.
The fix
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends nginx && rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
docker run -d --name fix8-bld-web -p 127.0.0.1:15881:80 fix8-bld-p3fix
...
curl.exe -s -o NUL -w "%{http_code}`n" http://127.0.0.1:15881/
200
Process 1 in that container is nginx: master process nginx -g daemon off;, and
the page answered 200. daemon off; matters: without it nginx forks into the
background, process 1 exits and the container stops (the same image started with plain
nginx showed Exited (0) three seconds later). For an interactive test in an existing
container, service nginx start answered * Starting nginx nginx ...done.
where systemctl had failed. Several services in one image call for one container
each, wired together with Compose.
How it was reproduced
docker run -d --name fix8-bld-sysd ubuntu:24.04 sleep 900, then
apt-get install of systemd and nginx inside it with
docker exec, then systemctl start nginx. Ubuntu 24.04.5, systemd
255, nginx 1.24.0, Docker Desktop engine 29.9.2. The container, image and port are this
test's own.
Frequently asked
- Why does systemctl not work in a Docker container?
- systemctl talks to systemd, which must be process 1. In a container process 1 is the image's CMD or ENTRYPOINT, so there is no systemd and no bus to connect to.
- How do I start a service inside a Docker container?
- Make the program the container's CMD and run it in the foreground, for example nginx -g daemon off. For a quick manual test, service name start uses the init script and works.
- Should I run systemd inside Docker?
- Usually not. Docker already restarts, logs and health-checks the main process. Run one service per container and connect several with Docker Compose.
More decoded errors in the Fixes category. To split an app and its database into containers, see Compose for an app and its database.