Docker executor with systemd

One of my projects requires systemd to run in the background.
This is perfectly fine for use when installed on the system.
But for testing with gitlab and a docker executor, this is bad.

I can run a docker container with systemd installed.
The entrypoint has to be “/lib/systemd/systemd” (it needs to have PID 1).
Systemd starts and gets to a login shell. I can bypass this and
automatically login to the system.
So “docker run …” gives me a shell in the container.

However, gitlab passes a script to the container upon start.
That would make that script to be PID 1 which does not work with systemd.

Is there another way to get this to work?

I would like to do the following:
(1) “docker run” starts the container, and
(2) “docker exec” runs the script.

Thanks for taking the time to be thorough in your request, it really helps! :blush:*

Hi @Dennis_1 :wave:

I’ve encountered this same problem before and I couldn’t figure out any way to get systemd to work with GitLab Runner Docker executor. If anyone knows how to do this, please share! :pray:

A potential workaround could be using GitLab Runner’s Shell executor on a machine with Docker installed for any CI jobs that require systemd and docker.

1 Like

I believe @nicolamori managed to solve this see this post on stackoverflow, however my attempt to duplicate it initially resulted in a Docker container which, when run on a non-privileged runner, simply returned ERROR: Job failed: exit code 255, however when run on a privileged runner it works perfectly on Debian Bookworm and Ubuntu Jammy however with Debian Bullseye the CI job doesn’t terminate until the GitLab CI timeout is reached — however this might be a molecule issue?

The only part of this potential solution I’ve written myself is the last section of the Dockerfile:

COPY entrypoint.sh /entrypoint.sh
COPY bash.service /etc/systemd/system/bash.service
RUN chown root:root /entrypoint.sh \
    && chmod 755 /entrypoint.sh \
    && chown root:root /etc/systemd/system/bash.service \
    && chmod 644 /etc/systemd/system/bash.service \
    && systemctl enable bash.service
ENTRYPOINT ["/entrypoint.sh"]

Everything else has been copied from the stackoverflow comment linked above.

The only additional Debian package I have installed in the container, for this (I’m doing other things like installing Ansible) is systemd.

Note that for Debian Bullseye systemd is at /lib/systemd/systemd rather than /usr/lib/systemd/systemd where it is found for Debian Bookworm and Ubuntu Jammy.

One potential improvement that the entrypoint.sh script could do with is a check if the container is running in privileged mode with a error message being returned if it is not, see for example the suggestion here however this might not be possible as the check might interfere with the PID assignment?