Run /sbin/init as PID 1, and return shell

Hi,

How can I run /sbin/init as PID 1, and return a shell as GitLab CI requires? (Disclaimer: I am aware running systemd inside containers almost never makes sense; my use case is the one in which it does: testing systemd itself.)

Running systemd works using Podman and the following Dockerfile:

FROM debian:latest

RUN apt-get update
RUN apt-get -y install systemd systemd-sysv

ENTRYPOINT ["/sbin/init"]

At this point, my container is booted with systemd as PID 1.

But this doesn’t work with GitLab CI. It needs a shell, so GitLab passes the following command (hardcoded):

sh -c if [ -x /usr/local/bin/bash ]; then
                                                                  exec /usr/local/bin/bash
elif [ -x /usr/bin/bash ]; then
            exec /usr/bin/bash
elif [ -x /bin/bash ]; then
            exec /bin/bash
elif [ -x /usr/local/bin/sh ]; then
            exec /usr/local/bin/sh
elif [ -x /usr/bin/sh ]; then
            exec /usr/bin/sh
elif [ -x /bin/sh ]; then
            exec /bin/sh
elif [ -x /busybox/sh ]; then
            exec /busybox/sh
else
            echo shell not found
            exit 1
fi

This command is passed to the ENTRYPOINT as documented. So, I end up with the following invalid process:

root           1  0.2  0.6  20600 12480 ?        Ss   08:24   0:00 /sbin/init sh -c if [ -x /usr/local/bin/bash ]; then .exec /usr/local/bin/bash  elif [ -x /usr/bin/bash ]; then .exec /usr/bin/bash  elif [ -x /bin/bash ]; then .exec /bin/bash  elif [ -x /usr/local/bin/sh ]; then .exec /usr/local/bin/sh  elif [ -x /usr/bin/sh ]; then .exec /usr/bin/sh  elif [ -x /bin/sh ]; then .exec /bin/sh  elif [ -x /busybox/sh ]; then .exec /busybox/sh  else .echo shell not found .exit 1 fi

Note how the entrypoint and command have been concatenated. The container eventually times out.

I thought I can work around this. I wrapped /sbin/init in a script that also takes GitLab’s command, therefore starting systemd and returning a shell:

$ grep ENTRYPOINT Dockerfile
ENTRYPOINT ["./docker-entrypoint.sh"]

$ cat docker-entrypoint.sh
#!/bin/bash

set -e

exec /sbin/init
/bin/bash

But this (obviously) doesn’t work: using anything else than /sbin/init as the entrypoint will cause it to not be PID 1. In userland, that causes errors such as:

System has not been booted with systemd as init system (PID 1). Can’t operate.

So, being unable to use a wrapper script, that brings us back to the original issue: how do I start /sbin/init as PID 1 (= it must be passed to ENTRYPOINT directly), and return a shell as GitLab requires?

Anyone have smart ideas?