13

In a Dockerfile, the common way to copy a directory as a non-root user (e.g $UID 1000) is the following:

COPY --chown=1000:1000 /path/to/host/dir/ /path/to/container/dir

However, I want to use variables instead. For example

ARG USER_ID=1000
ARG GROUP_ID=1000
COPY --chown=${USER_ID}:${GROUP_ID} /path/to/host/dir/ /path/to/container/dir

But this is not possible. There exist a workaround?

Note I know that a possible workaround could be to copy the directory as root and then run chown on the directory (variables works fine with RUN). However, the size of the image will grow just for the use of chown in a separate command.

gvgramazio
  • 1,115
  • 3
  • 13
  • 30
  • 2
    I believe you can do it with more recent versions of docker - I'm copying files the same way you do (`COPY --chown=${USER_ID}:${GROUP_ID}`), and it works just fine – aurelia Apr 04 '22 at 12:10

2 Answers2

10

You can create a user before running the --chown;

mkdir -p test && cd test
mkdir -p path/to/host/dir/
touch path/to/host/dir/myfile

Create your Dockerfile:

FROM busybox

ARG USER_ID=1000
ARG GROUP_ID=1000

RUN addgroup -g ${GROUP_ID} mygroup \
 && adduser -D myuser -u ${USER_ID} -g myuser -G mygroup -s /bin/sh -h /

COPY --chown=myuser:mygroup /path/to/host/dir/ /path/to/container/dir

Build the image

docker build -t example .

Or build it with a custom UID/GID:

docker build -t example --build-arg USER_ID=1234 --build-arg GROUP_ID=2345 .

And verify that the file was chown'ed

docker run --rm example ls -la /path/to/container/dir

total 8
drwxr-xr-x    2 myuser   mygroup       4096 Dec 22 16:08 .
drwxr-xr-x    3 root     root          4096 Dec 22 16:08 ..
-rw-r--r--    1 myuser   mygroup          0 Dec 22 15:51 myfile

Verify that it has the correct uid/gid:

docker run --rm example ls -lan /path/to/container/dir

total 8
drwxr-xr-x    2 1234     2345          4096 Dec 22 16:08 .
drwxr-xr-x    3 0        0             4096 Dec 22 16:08 ..
-rw-r--r--    1 1234     2345             0 Dec 22 15:51 myfile

Note: there is an open feature-request for adding this functionality: issue #35018 "Allow COPY command's --chown to be dynamically populated via ENV or ARG"

thaJeztah
  • 27,738
  • 9
  • 73
  • 92
  • I almost have the same problem. In the sense that `myuser` can't be substituted by a variable like `$USERNAME`. However, it's not a problem for me to have a fixed name of the user. What I needed was a variable user id and group id. Long story short: you solved my problem but only because the username can be fixed in my use case. – gvgramazio Dec 22 '18 at 16:21
  • Do you want to change the UID/GID because (during development) you'd want to make them match your local user (and bind-mount your source inside the container)? You may be interested in this dirty trick (from @bmitch); https://sudo-bmitch.github.io/presentations/dc2018eu/tips-and-tricks-of-the-captains.html#49 The whole presentation is worth reading (you can also find it on GitHub https://github.com/sudo-bmitch/presentations) – thaJeztah Dec 22 '18 at 16:58
0

In my case, I used my UID and GID numbers and it works as I do have the same non-root account in the DEV and PROD environments.

COPY --chown=1000:1000 /path/to/host/dir/ /path/to/container/dir

And you can find the user and group IDs with the linux command: id

Fedor
  • 17,146
  • 13
  • 40
  • 131