266

While building a Docker image, how do I COPY a file into the image so that the resulting file is owned by a user other than root?

FGreg
  • 14,110
  • 10
  • 68
  • 110

2 Answers2

403

For versions v17.09.0-ce and newer

Use the optional flag --chown=<user>:<group> with either the ADD or COPY commands.

For example

COPY --chown=<user>:<group> <hostPath> <containerPath>

The documentation for the --chown flag is now live on the main Dockerfile Reference page.

Issue 34263 has been merged and is available in release v17.09.0-ce.


For versions older than v17.09.0-ce

Docker doesn't support COPY as a user other than root. You need to chown / chmod the file after the COPY command.

Example Dockerfile:

from centos:6
RUN groupadd -r myuser && adduser -r -g myuser myuser
USER myuser
#Install code, configure application, etc...
USER root
COPY run-my-app.sh /usr/local/bin/run-my-app.sh
RUN chown myuser:myuser /usr/local/bin/run-my-app.sh && \
    chmod 744 /usr/local/bin/run-my-app.sh
USER myuser
ENTRYPOINT ["/usr/local/bin/run-my-app.sh"]

Previous to v17.09.0-ce, the Dockerfile Reference for the COPY command said:

All new files and directories are created with a UID and GID of 0.


History This feature has been tracked through multiple GitHub issues: 6119, 9943, 13600, 27303, 28499, Issue 30110.

Issue 34263 is the issue that implemented the optional flag functionality and Issue 467 updated the documentation.

Chris H.
  • 2,204
  • 1
  • 19
  • 18
FGreg
  • 14,110
  • 10
  • 68
  • 110
  • 4
    This is frustating, since chown-ing a lot of files has become an incredibly slow since the overlay2 has become the default storage-driver – hbogert Aug 14 '17 at 16:08
  • 2
    Yep, besides, it creates a large extra image layer for no apparent reason (in my case: >300MB for running `chown` on 40MB of files). – Dirk Nov 15 '17 at 12:17
  • 2
    There is one benefit also for running chown along with COPY command which is size reduction. If we run those two command separately (COPY ; chown other_user:other_user) then it created one extra layer which eventually doubles the image size. – abhishek thakur Dec 05 '18 at 05:12
  • This answer is a lifesaver. Thank you so much, solved a problem I'd been fighting for a few hours. – Colby Hill Jun 23 '20 at 18:36
  • 1
    We found out the hard way that the docker server version is important. – GaTechThomas Jan 28 '21 at 22:05
0

i did like this & is perfectly

FROM node:lts-alpine3.17
RUN addgroup app && adduser -S -G app app
RUN mkdir /app && chown app:app /app
USER app
WORKDIR /app
COPY --chown=app:app package*.json .
RUN npm install
COPY --chown=app:app . .
EXPOSE 8090
CMD ["npm","start"]