docker-node: Adding a non-root user with UID 1000 breaks custom builds

When using node as base image to build my own images, I usually create a user with UID 1000 (due to some internal restriction, this UID must be 1000), but now with node creating a user with UID 1000 by itself, my Dockerfiles no longer builds.

As Dockerfiles is now, it is not possible to fix this issue without having to fork it.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 17 (12 by maintainers)

Commits related to this issue

Most upvoted comments

I have this pattern where I create a user inside containers based on build args: First I add default values at the top of the dockerfile:

ARG HOST_USER_UID=1000
ARG HOST_USER_GID=1000

Then I have this RUN instruction:

RUN set -ex                                                 && \
                                                               \
    echo 'Creating notroot user and group from host'        && \
    groupadd -g $HOST_USER_GID notroot                      && \
    useradd -lm -u $HOST_USER_UID -g $HOST_USER_GID notroot

Then I use the notroot name when i have to change permissions and execute commands:

RUN set -ex                                                 && \
                                                               \
    echo 'Giving permissions to files'                      && \
    chown -R notroot:notroot /work                          && \
                                                               \
    echo 'Installing yarn'                                  && \
    npm install -g yarn                                     && \
                                                               \
    echo 'Installing production packages as notroot'        && \
    runuser notroot -c "                                       \
      cd /work                                              && \
      yarn install                                             \
        --modules-folder /home/notroot/node_modules            \
        --production                                           \
    "

To build I just pass build args in the docker-compose.yml:

build:
  args:
    HOST_USER_UID: ${HOST_USER_UID}
    HOST_USER_GID: ${HOST_USER_GID}

Or in the cli:

docker build \
  --build-arg HOST_USER_UID=`id -u` \
  --build-arg HOST_USER_GID=`id -g` \
  ...

The change introduced in this PR breaks this kind of workflow.

This might only affect me and a few other people and yes, there are simple workarounds and you have no reason to care about how I build stuff downstream but what is the reason to add such a user if you are not using it during the build process, nor is it enforced as the image default user.

Anybody who needs or wants such a user will just create one themselves based on their workflow (as I did above). Also the default uid/gid of 1000 is useless if the host user is created through logging in with Active Directory, or if someone simply uses a different uid/gid combination.

Right now I’m using the userdel -r node workaround.

</rant> Just my 2¢, feel free to ignore

@rafaelsierra If simply using the provided node user is not an option, the following RUN command added in your Dockerfile should allow you to use the base Node images without having to fork:

RUN groupmod -g 1001 node \
  && usermod -u 1001 -g 1001 node

This simply changes the user/group ID of node to 1001, freeing up the ID 1000.

Alternatively, you could also delete the node user and group in a RUN command if you don’t need them.

I agree with @sdwolf. We have the same workflow.

IMHO, it’s not the role of a base image to make some assumptions on the execution environment. When a specific user is not absolutely required, like in this case, using a non-root user should be of the final user’s responsibility and not of the base image.

Closing as the corresponding doc updates landed a while ago: https://github.com/nodejs/docker-node/commit/c3694d8baa8a95472c007af5cadbb0068b81618e

who in the heck added the node user? there wasn’t any on version 4.4.5 for sure

I haven’t tested this but since the image runs as root, couldn’t you rename the node user to whatever you like in your Dockerfile?

RUN usermod -d /home/newname -l newname node

Well, if you ask me, any Docker image should ideally use a non-privileged user. The node Docker group decided to add one by default called node. Although it’s not used by default, it’s only a USER node Dockerfile instruction away.

For compatibility with host-mounts on docker-machine setups on OSX, I recommended to use 1000 as ID, probably the same reason you’re using that. This recommendation was merged, so any node Docker image now has a node user with ID 1000.

As far as breaking compatibility goes, simply adding the node user already broke dependant Docker images (e.g. all that added a node user by themselves). But I think fixing downstream images is easy and I also don’t think the node Docker group makes those decisions without consideration (e.g. there were multiple reviews), so I’d say it’s safe to say that those changes will stay.