Faisal Shani
Faisal Shani

Reputation: 810

Running a process with nobody user with gosu

I am trying to run a process with nobody user in Linux, currently this is being run as a root user but since this process doesn't require the root access so I want to use nobody with gosu. The problem is even after activating the nobody user and running the process with that, when I do " ps aux" it shows that all processes are being run by root. Do I need to do something more after activating the nobody user to make it possible to run the process. The process I am trying to run with nobody is rails s -b 0.0.0.0

Below is my dockerfile

FROM ruby:3.0.1
EXPOSE $PORT
WORKDIR /srv
COPY Gemfile Gemfile.lock /srv/
COPY . /srv
RUN apt-get update -qq && apt-get install -y build-essential iproute2 libpq-dev nodejs && apt- 
get clean && bundle install --no-cache

#activating the nobody user account
RUN chsh -s /bin/bash nobody

RUN set -eux; \
    apt-get install -y gosu; \
    rm -rf /var/lib/apt/lists/*; \
    gosu nobody true
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["server"]

Here is the docker-entrypoint.sh

#!/bin/sh
export BASH_SHELL=$(cat /etc/shells | grep /bash)
export ASH_SHELL=$(cat /etc/shells | grep /ash)
#Setting available Shell to $SHELL_PROFILE
if [ -n "$BASH_SHELL" ];
then
 SHELL_PROFILE=$BASH_SHELL
elif [ -n "$ASH_SHELL" ];
then
  SHELL_PROFILE=$ASH_SHELL
else
  SHELL_PROFILE=sh
fi
rm -f tmp/pids/puma.5070.pid tmp/pids/server.pid

XRAY_ADDRESS="$(ip route | grep default | cut -d ' ' -f 3):2000"
export AWS_XRAY_DAEMON_ADDRESS=$XRAY_ADDRESS
echo "export AWS_XRAY_DAEMON_ADDRESS=$XRAY_ADDRESS" >> /root/.bashrc

case "$*" in
  shell)
    exec $SHELL_PROFILE
    ;;
  server)
    
    # gosu command to run rails s -b 0.0.0.0 process as nobody user
    gosu nobody:nogroup bundle exec rails s -b 0.0.0.0
    ;;
  *)
    exec $@
    ;;
esac

Upvotes: 0

Views: 5158

Answers (1)

David Maze
David Maze

Reputation: 159171

Don't bother installing gosu or another tool; just set your Docker image to run as the nobody user (or some other non-root user). Do this at the very end of your Dockerfile, where you otherwise declare the CMD.

# Don't install gosu or "activate a user"; but instead
USER nobody
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["rails", "server", "-b", "0.0.0.0"]

In turn, that means you can remove the gosu invocation from the entrypoint script. I might remove most of it and trim it down to

#!/bin/sh

# Clean up stale pid files
rm -f tmp/pids/*.pid

# (Should this environment variable be set via `docker run`?)
export AWS_XRAY_DAEMON_ADDRESS="$(ip route | grep default | cut -d ' ' -f 3):2000"

# Run whatever the provided command was, in a Bundler context
exec bundle exec "$@"

If you need an interactive shell to debug the image, you can docker run --rm -it the-image bash which works on many images (provided they (a) honor CMD and (b) have bash installed); you don't need a special shell artificial command and you don't need to detect what's installed in the (fixed) image.

Upvotes: 1

Related Questions