简体   繁体   中英

Dockerfile - Creating non-root user almost doubles the image size

Created an application image on top of ubuntu. The application requires a non-root user.

I am able to create the image and get it working but the RUN statement for creating new user significantly increases the size of this image.

Dockerfile snippet:

  ## create newuser and give correct permissions to home directory
  RUN useradd newuser --create-home --shell /bin/bash  && \
      echo 'newuser:newpassword' | chpasswd && \
      chown -R newuser:newuser /home/newuser && \
      chmod 755 /home/newuser

  USER newuser

  WORKDIR /home/newuser

Is there a better way to create a new user?

Thinking about alternate approaches, wonder if one uses multi-stage build to create this new user and then use copy --from to get relevant files in the final build. Not sure what those files would be.

Don't chown the directory; leave root owning it. You also shouldn't need to set a shell, or a password, or create a home directory; none of these things will be used in normal operation.

I'd suggest creating the user towards the start of the Dockerfile (it is fairly fixed and so this step can be cached) but only switching USER at the very end of the file, when you're setting up the metadata for how to run the container.

A Node-based example:

FROM node:lts # debian-based

# Create the non-root user up front
RUN adduser --system --group --no-create-home newuser

# Copy and build the package as usual
WORKDIR /app
COPY package.json yarn.lock .
RUN yarn install
COPY . .
RUN yarn build

# Now the application is built
# And root owns all the files
# And that's fine

# Say how to run the container
EXPOSE 3000
USER newuser
CMD yarn start

Having root owning the files gives you a little extra protection in case something goes wrong. If there's a bug that allows files in the container to be overwritten, having a different user owning those files prevents the application code or static assets from being inadvertently modified.

If your application needs to read or write files then you could create a specific directory for that:

 # Towards the end of the file, but before the USER
 RUN mkdir data && chown newuser data

This will let the operator mount some storage over the otherwise-empty directory. This is the only thing that has the newly created user ID in it at all, so if the storage comes with its own owner it shouldn't be an operational problem; you need to also specify the matching user ID at container startup time.

docker run -u $(id -u) -v $PWD/data:/app/data ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM