Home > Software design >  How to run ENTRYPOINT as root and switch to non-root to run CMD using gosu?
How to run ENTRYPOINT as root and switch to non-root to run CMD using gosu?

Time:10-17

To connect to my container from Azure WebApp admin I need to start ssh server at startup. Then I need to run web server once the db is up.

In my Dockerfile I create a dedicated non-root user to run the web server.

RUN groupadd -g 1000 wagtail && \
    useradd -u 1000 wagtail -m -d /home/wagtail -g wagtail

I copy startup-ssh.sh and startup-main.sh scripts into the container:

COPY startup-ssh.sh /app/
COPY startup-main.sh /app/
RUN chmod  x /app/startup-ssh.sh
RUN chmod  x /app/startup-main.sh
ENTRYPOINT ["/bin/bash", "-c", "/app/startup-ssh.sh"]
CMD ["/bin/bash", "-c", "/app/startup-main.sh"]

In the startup-ssh.sh I start the ssh server and then use gosu to switch user:

#!/bin/bash

# start ssh server
sed -i "s/SSH_PORT/$SSH_PORT/g" /etc/ssh/sshd_config
/usr/sbin/sshd

# restore /app directory rights
chown -R wagtail:wagtail /app

# switch to the non-root user
exec gosu wagtail "$@"

I expect the CMD's startup-main.sh script to be executed next but I get this in the Docker Desktop logs when the container is started.

Exited(1)
Usage: gosu user-spec command [args]
   gosu nobody:root bash -c 'whoami && id'
   gosu 1000:1 idie: gosu tianon bash

gosu version: 1.10 (go1.11.5 on linux/amd64; gc)
   license: GPL-3 (full text at https://github.com/tianon/gosu)

I believe that Docker Desktop uses root when connecting to the container.

Maybe I'm missing something critical and/or this is something obvious. Please point me.

CodePudding user response:

The code passed no arguments to the script. Imagine it like this:

bash -c '/app/startup-ssh.sh <NO ARGUMENTS HERE>' ignored ignored2 ignored3...

Test:

bash -c 'echo' 1
bash -c 'echo' 1 2
bash -c 'echo $0' 1 2 3
bash -c 'echo $1' 1 2 3
bash -c 'echo "$@"' 1 2 3

You want:

ENTRYPOINT ["/bin/bash", "-c", "/app/startup-ssh.sh \"$@\"", "--"]

Or, why the explicit shell if the file has a shebang and is executable, really just:

ENTRYPOINT ["/app/startup-ssh.sh"]
  • Related