I am trying to match the host UID with container UID as below.
Dockerfile
RUN addgroup -g 1000 deploy \
&& adduser -D -u 1000 -G deploy -s /bin/sh deploy
USER deploy
COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm7","-F"]
entrypoint.sh
whoami # it outputs `deploy`
# Change UID of 'deploy' as per host user UID
HOST_CURRENT_USER_ID=$(stat -c "%u" /var/www/${PROJECT_NAME})
if [ ${HOST_CURRENT_USER_ID} -ne 0 ]; then
gosu root usermod -u ${HOST_CURRENT_USER_ID} deploy
gosu root groupmod -g ${HOST_CURRENT_USER_ID} deploy
fi
whoami # It outputs as unknown user id 1000.
Please note the output of whoami
above. Even If I changed the UID of deploy to host uid, the entrypoint script process doesn't get changed as the entrypoint shell has been called by UID 1000.
So I came up in a solution to make two entry point script one is to change the UID and another one is for container's bootstrap process which will be run in a separate shell after I change the UID of deploy. So how can I make two entrypoint run after another. E.g something like
ENTRYPOINT ["/fix-uid.sh && /entrypoint.sh"]
It looks like you're designing a solution very similar to one that I've created. As ErikMD mentions, do not use gosu to switch from a user to root, you want to go the other way, from root to a user. Otherwise, you will have an open security hole inside your container than any user can become root, defeating the purpose of running a container as a different user id.
For the solution that I put together, I have it work whether the container is run in production as just a user with no volume mounts, or in development with volume mounts by initially starting the container as root. You can have an identical Dockerfile, and change the entrypoint to have something along the lines of:
The
fix-perms
script above is from my base image, and includes the following bit of code:(Note, I really like your use of
stat -c
and will likely be updating myfix-perms
script to leverage that over thels
command I have in there now.)The important part to this is running the container. When you need the
fix-perms
code to run (which for me is only in development), I start the container as root. This can be adocker run -u root:root ...
oruser: "root:root"
in a compose file. That launches the container as root initially, which triggers the first half of the if/else in the entrypoint that runsfix-perms
and then runs agosu deploy
to drop from root to deploy before calling "$@" which is your command (CMD). The end result is pid 1 in the container is now running your command as the deploy user.As an aside, if you really want an easier way to run multiple entrypoint fragments in a way that's easy to extend with child images, I use an
entrypoint.d
folder that is processed by an entrypoint script in my base image. To code to implement that logic is as simple as:All of this can be seen, along with an example using nginx, at: https://github.com/sudo-bmitch/docker-base
The behavior you observe seems fairly normal: in your entrypoint script, you changed the UID associated with the username
deploy
, but the twowhoami
commands are still run with the same user (identified by the UID in the first place, not the username).For more information about UIDs and GIDs in a Docker context, see e.g. that reference.
Note also that using
gosu
to re-become root is not a standard practice (see in particular that warning in the upstream doc).For your use case, I'd suggest removing the
USER deploy
command and switch user in the very end, by adapting your entrypoint script as follows: