├── Dockerfile ├── Makefile ├── README.md ├── apt_periodic ├── apt_unattended-upgrades ├── configurator.service ├── configurator.sh ├── configurator_dumpenv.service ├── configurator_dumpenv.sh ├── container-boot.service ├── preferences └── sources.list /Dockerfile: -------------------------------------------------------------------------------- 1 | 2 | FROM debian:stretch 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | ENV container docker 6 | 7 | MAINTAINER Sebastian Krohn 8 | 9 | # add contrib, non-free and backports repositories 10 | ADD sources.list /etc/apt/sources.list 11 | # pin stable repositories 12 | ADD preferences /etc/apt/preferences 13 | 14 | # clean out, update and install some base utilities 15 | RUN apt-get -y update && apt-get -y upgrade && apt-get clean && \ 16 | apt-get -y install apt-utils lsb-release curl git cron at logrotate rsyslog \ 17 | unattended-upgrades ssmtp lsof procps \ 18 | initscripts libsystemd0 libudev1 systemd sysvinit-utils udev util-linux && \ 19 | apt-get clean && \ 20 | sed -i '/imklog/{s/^/#/}' /etc/rsyslog.conf 21 | 22 | # set random root password 23 | RUN P="$(dd if=/dev/random bs=1 count=8 2>/dev/null | base64)" ; echo $P && echo "root:$P" | chpasswd 24 | # set to foobar 25 | #RUN P="foobar" ; echo $P && echo "root:$P" | chpasswd 26 | 27 | # unattended upgrades & co 28 | ADD apt_unattended-upgrades /etc/apt/apt.conf.d/50unattended-upgrades 29 | ADD apt_periodic /etc/apt/apt.conf.d/02periodic 30 | 31 | 32 | RUN cd /lib/systemd/system/sysinit.target.wants/ && \ 33 | ls | grep -v systemd-tmpfiles-setup.service | xargs rm -f && \ 34 | rm -f /lib/systemd/system/sockets.target.wants/*udev* && \ 35 | systemctl mask -- \ 36 | tmp.mount \ 37 | etc-hostname.mount \ 38 | etc-hosts.mount \ 39 | etc-resolv.conf.mount \ 40 | -.mount \ 41 | swap.target \ 42 | getty.target \ 43 | getty-static.service \ 44 | dev-mqueue.mount \ 45 | cgproxy.service \ 46 | systemd-tmpfiles-setup-dev.service \ 47 | systemd-remount-fs.service \ 48 | systemd-ask-password-wall.path \ 49 | systemd-logind.service && \ 50 | systemctl set-default multi-user.target || true 51 | 52 | RUN sed -ri /etc/systemd/journald.conf \ 53 | -e 's!^#?Storage=.*!Storage=volatile!' 54 | ADD container-boot.service /etc/systemd/system/container-boot.service 55 | RUN mkdir -p /etc/container-boot.d && \ 56 | systemctl enable container-boot.service 57 | 58 | 59 | 60 | # run stuff 61 | ADD configurator.sh configurator_dumpenv.sh /root/ 62 | ADD configurator.service configurator_dumpenv.service /etc/systemd/system/ 63 | RUN chmod 700 /root/configurator.sh /root/configurator_dumpenv.sh && \ 64 | systemctl enable configurator.service configurator_dumpenv.service 65 | 66 | VOLUME [ "/sys/fs/cgroup", "/run", "/run/lock", "/tmp" ] 67 | CMD ["/lib/systemd/systemd"] 68 | 69 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: 3 | docker build -t dramaturg/debian-systemd . 4 | 5 | rebuild: 6 | docker pull debian:jessie 7 | docker build --no-cache=true -t dramaturg/debian-systemd . 8 | 9 | push: 10 | docker tag dramaturg/debian-systemd dramaturg/debian-systemd:$$(date +%Y%m%d) 11 | docker push dramaturg/debian-systemd 12 | 13 | run: 14 | docker run -d -i -t -v /sys/fs/cgroup:/sys/fs/cgroup:ro dramaturg/debian-systemd 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-debian-systemd 2 | 3 | Debian container running systemd in unpriviledged mode 4 | 5 | start like this: 6 | ``` 7 | docker run -d -t -i -v /sys/fs/cgroup:/sys/fs/cgroup:ro dramaturg/debian-systemd 8 | ``` 9 | 10 | Or use supplied makefile. 11 | 12 | 13 | ## Basing containers on this 14 | 15 | Docker environment variables are imported into systemd when the container starts up - see configurator_dumpenv.sh 16 | 17 | If you need to change a configuration file based on docker environment variables, check out configurator.sh. It too runs when the container first starts up. 18 | 19 | 20 | ## Gotchas 21 | 22 | * backports are enabled and pinned to be used. 23 | * cron, rsyslogd and atd are running, reconfigure or disable as required 24 | * unattended upgrades are enabled 25 | 26 | -------------------------------------------------------------------------------- /apt_periodic: -------------------------------------------------------------------------------- 1 | // Enable the update/upgrade script (0=disable) 2 | APT::Periodic::Enable "1"; 3 | 4 | // Do "apt-get update" automatically every n-days (0=disable) 5 | APT::Periodic::Update-Package-Lists "1"; 6 | 7 | // Do "apt-get upgrade --download-only" every n-days (0=disable) 8 | APT::Periodic::Download-Upgradeable-Packages "1"; 9 | 10 | // Run the "unattended-upgrade" security upgrade script 11 | // every n-days (0=disabled) 12 | // Requires the package "unattended-upgrades" and will write 13 | // a log in /var/log/unattended-upgrades 14 | APT::Periodic::Unattended-Upgrade "1"; 15 | 16 | // Do "apt-get autoclean" every n-days (0=disable) 17 | APT::Periodic::AutocleanInterval "7"; 18 | 19 | -------------------------------------------------------------------------------- /apt_unattended-upgrades: -------------------------------------------------------------------------------- 1 | 2 | Unattended-Upgrade::Origins-Pattern { 3 | "o=${distro_id},n=${distro_codename}"; 4 | "o=${distro_id},n=${distro_codename}-updates"; 5 | "o=${distro_id},n=${distro_codename},l=Debian-Security"; 6 | }; 7 | 8 | Unattended-Upgrade::Package-Blacklist { 9 | // "libc6"; 10 | }; 11 | 12 | Unattended-Upgrade::AutoFixInterruptedDpkg "true"; 13 | Unattended-Upgrade::MinimalSteps "true"; 14 | Unattended-Upgrade::Mail "root"; 15 | Unattended-Upgrade::MailOnlyOnError "true"; 16 | Unattended-Upgrade::Remove-Unused-Dependencies "true"; 17 | Acquire::http::Dl-Limit "700"; 18 | 19 | -------------------------------------------------------------------------------- /configurator.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Configure stuff from environment variables 3 | ConditionFileIsExecutable=/root/configurator.sh 4 | Requires=configurator_dumpenv.service 5 | After=configurator_dumpenv.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/root/configurator.sh 10 | TimeoutSec=0 11 | StandardOutput=inherit 12 | RemainAfterExit=yes 13 | 14 | [Install] 15 | WantedBy=basic.target 16 | -------------------------------------------------------------------------------- /configurator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | set -o errexit 4 | set -o nounset 5 | 6 | for conffile in $(env | sed -n '/^conff./{s///;p}') 7 | do 8 | eval $(awk -F'=' '{print "service=\"" $1 "\""; print "conffile=\"" $2 "\""}' <<<$conffile) 9 | 10 | if [ ! -f "$conffile.tmpl" ] ; then 11 | cp "$conffile" "$conffile.tmpl" 12 | fi 13 | 14 | perl -pe 's/%%([^%]+)%%/$ENV{$1}/' < "$conffile.tmpl" > "$conffile" 15 | done 16 | 17 | -------------------------------------------------------------------------------- /configurator_dumpenv.service: -------------------------------------------------------------------------------- 1 | 2 | [Unit] 3 | Description=Dump the Docker environment variables 4 | Requires=container-boot.service 5 | After=container-boot.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/root/configurator_dumpenv.sh 10 | TimeoutSec=0 11 | StandardOutput=inherit 12 | RemainAfterExit=yes 13 | 14 | [Install] 15 | WantedBy=basic.target -------------------------------------------------------------------------------- /configurator_dumpenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash - 2 | 3 | xargs -n1 -0 bash -c 'echo "$0"; systemctl set-environment "$0"' \ 4 | < /proc/1/environ \ 5 | > /tmp/docker_environment 6 | 7 | chmod 700 /tmp/docker_environment 8 | 9 | -------------------------------------------------------------------------------- /container-boot.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Prepare container before starting services 3 | Before=basic.target 4 | After=sysinit.target 5 | DefaultDependencies=no 6 | 7 | [Service] 8 | ExecStart=/bin/run-parts -v --exit-on-error /etc/container-boot.d 9 | Type=oneshot 10 | RemainAfterExit=true 11 | 12 | [Install] 13 | WantedBy=basic.target 14 | -------------------------------------------------------------------------------- /preferences: -------------------------------------------------------------------------------- 1 | 2 | # < 0 - Never install Package 3 | # 1:100 - Only install if not installed in any other version 4 | # 100:500 - Only install if there is not a newer version installed and there is 5 | # no version in higher ranked distro 6 | # 500:990 - Install package if there is not a target release version or newer 7 | # version already installed 8 | # 990:1000 - Always install if there is not a newer version of the package already installed 9 | # > 1000 - Always install. Even if it means to downgrade. 10 | 11 | 12 | Package: * 13 | Pin: release n=stretch 14 | Pin-Priority: 900 15 | 16 | Package: * 17 | Pin: release n=stretch-backports 18 | Pin-Priority: 900 19 | 20 | Package: * 21 | Pin: release n=stretch-updates 22 | Pin-Priority: 900 23 | 24 | 25 | Package: * 26 | Pin: release n=stretch-proposed-updates 27 | Pin-Priority: 700 28 | 29 | Package: * 30 | Pin: release a=stable 31 | Pin-Priority: 900 32 | 33 | 34 | Package: * 35 | Pin: release a=testing 36 | Pin-Priority: 400 37 | 38 | Package: * 39 | Pin: release a=unstable 40 | Pin-Priority: -10 41 | 42 | -------------------------------------------------------------------------------- /sources.list: -------------------------------------------------------------------------------- 1 | 2 | deb http://http.debian.net/debian stretch main contrib non-free 3 | deb http://http.debian.net/debian stretch-backports main contrib non-free 4 | deb http://http.debian.net/debian testing main contrib non-free 5 | 6 | deb http://security.debian.org/ stretch/updates main contrib non-free 7 | deb-src http://security.debian.org/ stretch/updates main contrib non-free 8 | 9 | --------------------------------------------------------------------------------