ENTRYPOINT: first run command as root, then start shell for non-root user
Asked Answered
B

2

8

I'm writing a Dockerfile for an image that, when run, performs the following two things in order:

  1. Start up a daemon as root
  2. Start up an interactive shell as a non-root user

The problem is that ENTRYPOINT can only be run as a single user (whichever USER is set last before ENTRYPOINT in the Dockerfile). In this case, the ENTRYPOINT can only run as either root or the non-root user.

I can't put CMD commands before ENTRYPOINT, because they just get overridden by ENTRYPOINT.

How can I accomplish what I need?

Benavidez answered 22/5, 2019 at 21:41 Comment(1)
FYI: I have a workaround that is functioning but dirty. I put the non-root user in sudoers with no password, so my entrypoint script can now use sudo to start the daemon without having to provide a password.Benavidez
A
8

You start your container as root. This runs your entrypoint as root. Perform all the steps you need, then make the last step look like:

exec gosu username /bin/bash

To launch /bin/bash as the user username. You can find gosu in this github repo. It has the advantage of running an su command with an implicit exec which avoids leaving the parent process around which can break signal handling.

If you make /bin/bash the value of CMD, you can make this more flexible with:

exec gosu username "$@"

Make sure to use the JSON syntax for ENTRYPOINT and CMD to avoid issues with the merged commands and cli args.

This is preferable over sudo since it avoids any option to go back from the user to root.

Airlee answered 23/5, 2019 at 0:36 Comment(1)
You can add gosu to your Dockerfile using COPY clause: COPY --from=tianon/gosu /usr/local/bin/gosu /usr/local/bin/gosuFat
F
0

As alternative to @BMitch's answer, you can use another utilities like chroot or setpriv available in most distribution repositories.

chroot

With the --userspec=user[:group] flag, chroot can run a process as a different user and/or with a different primary group:

$ docker run -it --rm ubuntu:trusty chroot --userspec=nobody / ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nobody       1  5.0  0.0   7136   756 ?        Rs+  17:04   0:00 ps aux

setpriv

Available in newer util-linux (>= 2.32.1-0.2, in Debian; https://manpages.debian.org/buster/util-linux/setpriv.1.en.html):

$ docker run -it --rm buildpack-deps:buster-scm setpriv --reuid=nobody --regid=nogroup --init-groups ps faux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
nobody       1  5.0  0.0   9592  1252 pts/0    RNs+ 23:21   0:00 ps faux

su-exec

In the Alpine Linux ecosystem, su-exec is a minimal re-write of gosu in C, making for a much smaller binary, and is available in the main Alpine package repository.

(The above list was extracted from tianon/gosu's github repo).

Fat answered 29/7, 2024 at 6:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.