Running systemd inside a docker container (arch linux)
Solution 1:
Here my master pice :D running systemd inside a docker container with ubuntu :D I Got Ubuntu working with systemd inside docker
GitHub Repo for my docker-systemd container
$ docker run -it --cap-add SYS_ADMIN -v /sys/fs/cgroup:/sys/fs/cgroup:ro dockerimages/docker-systemd
Output:
systemd 218 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT -GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID -ELFUTILS +KMOD -IDN)
Detected virtualization 'docker'.
Detected architecture 'x86-64'.
Welcome to Ubuntu Vivid Vervet (development branch)!
Set hostname to <502ec40509a5>.
[ OK ] Created slice Root Slice.
[ OK ] Created slice System Slice.
Starting Emergency Shell...
[ OK ] Started Emergency Shell.
Startup finished in 5ms.
Welcome to emergency mode! After logging in, type "journalctl -xb" to view
system logs, "systemctl reboot" to reboot, "systemctl default" or ^D to
try again to boot into default mode.
root@502ec40509a5:~# exit
Update 2020
First of all base/archlinux image is deprecated - you should use archlinux/base instead. Then, to run systemd totally unprivileged, number of things should be done:
- provide a
container=
variable, so systemd won't try to do number of things it usually does booting a hardware machine - systemd actively uses cgroups, so bind mount
/sys/fs/cgroup
file system from a host - bind mounting
/sys/fs/fuse
is not required but helps to avoid issues with fuse-dependent software - systemd thinks that using
tmpfs
everywhere is a good approach, but running unprivileged makes it impossible for it to mounttmpfs
where ever it wants, so pre-mounttmpfs
to/tmp
,/run
and/run/lock
- as the last bit you need to specify
sysinit.target
as default unit to boot instead ofmulti-user.target
or whatever, as you really do not want to start graphical things inside a container
The resulting command line is
docker run \
--entrypoint=/usr/lib/systemd/systemd \
--env container=docker \
--mount type=bind,source=/sys/fs/cgroup,target=/sys/fs/cgroup \
--mount type=bind,source=/sys/fs/fuse,target=/sys/fs/fuse \
--mount type=tmpfs,destination=/tmp \
--mount type=tmpfs,destination=/run \
--mount type=tmpfs,destination=/run/lock \
archlinux/base --log-level=info --unit=sysinit.target
If we are talking about running particular service there like ntpd from your example you will need to add
--cap-add=SYS_TIME
otherwise ntpd
will fail with permission deny as nobody wants a container to set system time by default.
Solution 2:
To run systemd in a Docker container, the host system must also run systemd. This means you cannot use Ubuntu < 16.04 as the host.
Solution 3:
Currently systemd does not run correctly within a docker container, due to a whole set of reasons, i.e. the lack of the correct privileges. You can read up on that in a variety of github issues on the docker project like running systemd inside docker arch container hangs or segfaults and related issues regarding init/process monitoring. (I would like to link more issues here, but I can't as I apparently don't have enough reputation).
As you can see, this is a topic that is currently being worked on and a few patches have been merged already to improve behavior, so that we can expect this to work quite soon.
Apparently some developers already managed to get it to run on fedora systems, as they have documented in their blog.