How to use COPY --chown without losing portability (recently merged from this issue)? I'll try to explain with an example wherein I find --chown causing portability issues.
Let's say I got a base image (mybase) which I use for running other containers as non-root user (let's say with UID 1000) using gosu in ENTRYPOINT.
exec /usr/local/bin/gosu ${USER_NAME} "$@"
I use this base image (mybase) for building other container (let's say mycontainer) Dockerfile where I COPY some files from host to container using --chown
FROM mybase
RUN mkdir -p /tmp/build
COPY --chown=1000 . /tmp/build
Now I want the files generated via my build tool (from mycontainer) to be shared on a Docker Volume mapped with my host. Generated files would be available at specified host location but the owner of those files would be user with UID 1000. Doesn't this mean I'll need to have a user with UID 1000 on host machine for generated files to be accessible? Isn't there a way to provide value for --chown dynamically? I tired using ENV and ARG but they are not accessible in --chown.
ARG owner
COPY --chown=$owner . /tmp/build
it gives me an error
unable to convert uid/gid chown string to host mapping: can't find uid for user $owner: no such user: $owner
Steps to reproduce the issue:
FROM openjdk:8
ARG owner
ADD --chown=$owner . /tmp/build/platform3
CMD echo 'test'
sudo docker build -t test -f Dockerfile .Describe the results you received:
Result of running docker build
unable to convert uid/gid chown string to host mapping: can't find uid for user $owner: no such user: $owner
Describe the results you expected:
Expected result should be to get owner information from build arguments
Output of docker version:
Client:
Version: 17.09.0-ce
API version: 1.32
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:42:38 2017
OS/Arch: linux/amd64
Server:
Version: 17.09.0-ce
API version: 1.32 (minimum version 1.12)
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:41:20 2017
OS/Arch: linux/amd64
Experimental: false
Output of docker info:
Containers: 1
Running: 0
Paused: 0
Stopped: 1
Images: 15
Server Version: 17.09.0-ce
Storage Driver: aufs
Root Dir: /docker/pd0/aufs
Backing Filesystem: extfs
Dirs: 18
Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 06b9cb35161009dcb7123345749fef02f7cea8e0
runc version: 3f2f8b84a77f73d38244dd690525642a72156c64
init version: 949e6fa
Security Options:
apparmor
Kernel Version: 3.13.0-129-generic
Operating System: Ubuntu 14.04.5 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 14.69GiB
Name: ip-172-31-35-149
ID: KR63:RIDQ:SQNY:3ESC:5OA6:4DFT:QXSB:YE6M:727G:H7O2:REIS:RSFA
Docker Root Dir: /docker/pd0
Debug Mode (client): false
Debug Mode (server): false
Username: mavericksid
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
WARNING: No swap limit support
Now I want the files generated via my build tool (from mycontainer) to be shared on a Docker Volume mapped with my host. Generated files would be available at specified host location but the owner of those files would be user with UID 1000. Doesn't this mean I'll need to have a user with UID 1000 on host machine for generated files to be accessible?
If I understand your use-case correctly;
Dockerfile copies files from the host back to the image, but then has to match the user/group of the container's process?I think the _correct_ approach would be;
docker build, this could be done by an entrypoint script that does a chmod to set the correct permissions).Isn't there a way to provide value for
--chowndynamically? I tired usingENVandARGbut they are not accessible in--chown.
I'm not sure this is the correct approach for your use-case (see my bullets above), but you can create a user that uses the desired uid/gid and --chown to that user/group:
FROM openjdk:8
ARG uid=1001
ARG gid=51
RUN addgroup --gid $gid mygroup \
&& adduser --disabled-password --gecos "" --no-create-home --uid $uid --gid $gid myuser
COPY --chown=myuser:mygroup . /tmp/build/platform3
Also see https://github.com/moby/moby/issues/34482, and https://github.com/moby/moby/issues/34819 which may be relevant
I have the same issue - COPY --chown does not understand variables set via ENV or ARG earlier in the Dockerfile:
...
ARG AGENT_USER=agent
ARG AGENT_HOME=/home/agent
...
COPY --chown=$AGENT_USER:$AGENT_USER config/.ssh/config $AGENT_HOME/.ssh/config
...
This results in:
...
Step 15/16 : COPY --chown=$AGENT_USER:$AGENT_USER config/.ssh/config ${AGENT_HOME}/.ssh/config
unable to convert uid/gid chown string to host mapping: can't find uid for user $AGENT_USER: no such user: $AGENT_USER
If I hardcode the values, then everything works:
...
ARG AGENT_USER=agent
ARG AGENT_HOME=/home/agent
...
COPY --chown=agent:agent config/.ssh/config $AGENT_HOME/.ssh/config
...
I am also experiencing issue reported by @lmakarov where the the --chown doesn't honour ARG defined in the Dockerfile.
Guess this should be fixed?
Guess this should be fixed?
It's not a bug; environment-var expansion in command options is not implemented yet (this issue is a feature request)
Would be great to have that expanded by var-values some time in the future
This would really make my day!
What's the status on this issue; will it be relabeled to be included in 18.x?
No work has been done on this yet; if someone wants to work on this, I think this would be something that can be accepted as an enhancement.
When implementing, I think variable expansion should be implemented for the Dockerfile --options in general (so not just for --chown)
adding a +1 to be notified on progress
This would be super useful for a number of OSS projects I work on. As it stands, doing COPY --from=${SOME_IMAGE} only works with some sed hackery on the Dockerfile.
adding a +1 to be notified on progress
As @dimaspivak pointed out: this case is specific - as the other example in #36986
In general: Allow to interpret $ARG in COPY
It seems rather inconsistent that $ARG processing is supported in the arguments for COPY and ADD, except for the -- arguments
adding a +1 to be notified on progress
FWIW @jwarnier for that purpose, you have the subscribe button on the right.
+1
I've just fallen into this trap - trying to use ARG variable in COPY --from.
Is there any news from the devs whether is intentional or a mistake which will be fixed in due course?
+1! This would be useful for the WebSphere Application Server Docker image as well. Any updates?
@arthurdm:
The "--chown" COPY argument requires Docker 17.09 and up:
EDIT: disregard my comment, different topic :(
Hello, World.
Just wanted to say that it's 2019 and variable expansions in command options is still a high-valued feature request, at least for COPY --chown =)
What's the work around to lack of string expansion other than hard coding?
Run chown ${envvar}
For instance
Le dim. 31 mars 2019 Ã 06:04, Kim Carter notifications@github.com a
écrit :
What's the work around to lack of string expansion other than hard coding?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/moby/moby/issues/35018#issuecomment-478310131, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACcfr0IGust5-OyR_NHdLTXH7Yqf4Wg3ks5vcDPHgaJpZM4PnKcX
.
Thanks @pptime
Run chown ${envvar}
That's where I came from, it's too slow and adds an unnecessary additional image layer.
Yeah, I agree. It is anyway a trade-off to make. More layers sometimes
yield better cache usage.
Le dim. 31 mars 2019 Ã 11:30, Kim Carter notifications@github.com a
écrit :
Thanks @pptime https://github.com/pptime
Run chown ${envvar}
That's where I came from, it's too slow and adds an unnecessary additional
image layer.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/moby/moby/issues/35018#issuecomment-478326004, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACcfr-zlxpREIOx3ScGMPU7sfWJVUkBZks5vcIBQgaJpZM4PnKcX
.
@pptime @binarymist
Run chown ${envvar}
For instance
it's too slow and adds an unnecessary additional image layer.
More layers sometimes yield better cache usage.
It's not just a small layer that's added. Try to add a 100 MB file with COPY, then RUN chown [...] in the next layer, build the image, and inspect with dive.
Result: double data in your image. Efficiency down to 50% of the layer you add. Really not okay.
All right , that's horrible. Both for dev experience cause and storage
efficiency cause.
Could that be possible to remove or compress the intermediate layer like
the idea of git squash or fix-up?
Le dim. 31 mars 2019 Ã 12:05, Gert van Dijk notifications@github.com a
écrit :
@pptime https://github.com/pptime @binarymist
https://github.com/binarymistRun chown ${envvar}
For instance
it's too slow and adds an unnecessary additional image layer.
More layers sometimes yield better cache usage.
It's not just a small layer that's added. Try to add a 100 MB file with
COPY, then RUN chown [...] in the next layer, build the image, and
inspect with dive https://github.com/wagoodman/dive.Result: double data in your image. Efficiency down to 50% of the layer you
add. Really not okay.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/moby/moby/issues/35018#issuecomment-478328116, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ACcfr27v-s1yMwFnasIGRN3Pi0s_8CRhks5vcIiCgaJpZM4PnKcX
.
Could that be possible to remove or compress the intermediate layer like the idea of git squash or fix-up?
That's what multistage builds try and solve, but this issue is about something more fundamental I believe... something that seems intuitive, but doesn't yet exist sadly.
I guess the process is to first integrate moby/buildkit#926, then run vndr to update #39008.
If extendedly we need to have it compatible with the envvar set by a run command, then we need to think about an alternative implementation.
This is fixed on master now through https://github.com/moby/buildkit/pull/926, and https://github.com/moby/moby/pull/39132;
mkdir -p test && cd test
echo somefile > somefile.txt
cat > Dockerfile -<<'EOF'
FROM alpine
RUN addgroup --gid 456 onegrp \
&& adduser --disabled-password --no-create-home --uid 456 -G onegrp oneusr
RUN addgroup --gid 567 twogrp \
&& adduser --disabled-password --no-create-home --uid 567 -G twogrp twousr
ARG USR=oneusr
ARG GRP=onegrp
CMD ls -la /somefile.txt
COPY --chown=${USR}:${GRP} somefile.txt somefile.txt
EOF
Build the dockerfile, once without a build-arg (to use the default onegrp / oneusr), and once with:
docker build -t one .
docker build -t two --build-arg USR=twousr --build-arg GRP=twogrp .
Run the images to see that the user/group was set accordingly:
docker run --rm one
-rw-r--r-- 1 oneusr onegrp 9 Apr 25 17:37 /somefile.txt
docker run --rm two
-rw-r--r-- 1 twousr twogrp 9 Apr 25 17:37 /somefile.txt
In which version of docker can we expect this feature?
In which version of docker can we expect this feature?
Per my experiment this starts to work from docker 19.03.0
Just faced this situation. Upgrading docker it is not an alternative. Even so, it is not a straight solution, but works:
FROM ${IMAGE:-my-image}
ARG NAME
# I have already created a 'simple-user' and already inside its user's directory
RUN mkdir dependencies
# Here is the simple trick, switch to root
USER root
# Do the copies (no --chown flag required)
COPY ./dependencies/a ./dependencies/a
COPY ./dependencies/b ./dependencies/b
COPY ./dependencies/c ./dependencies/c
COPY ./dependencies/d ./dependencies/d
# It is time for admin performing all necessary modifications
RUN chmod -R +x ./dependencies/*.sh
# Variable substitution will work gracefully here, so root will delivery the directory ownership to the original 'simple-user'
RUN chown -R ${NAME}:${NAME} ./dependencies/*
# Switch back to 'simple-user' and continue doing the rest of the job
USER ${NAME}
Just faced this situation. Upgrading docker it is not an alternative. Even so, it is not a straight solution, but works:
FROM ${IMAGE:-my-image} ARG NAME # I have already created a 'simple-user' and already inside its user's directory RUN mkdir dependencies # Here is the simple trick, switch to root USER root # Do the copies (no --chown flag required) COPY ./dependencies/a ./dependencies/a COPY ./dependencies/b ./dependencies/b COPY ./dependencies/c ./dependencies/c COPY ./dependencies/d ./dependencies/d # It is time for admin performing all necessary modifications RUN chmod -R +x ./dependencies/*.sh # Variable substitution will work gracefully here, so root will delivery the directory ownership to the original 'simple-user' RUN chown -R ${NAME}:${NAME} ./dependencies/* # Switch back to 'simple-user' and continue doing the rest of the job USER ${NAME}
What do you mean by "switch to root"? you are already root by default. And COPY didn't honor USER command (not sure if it does now). Anyway, COPY --chown ... is several times faster than RUN chown ... (as in, more than 10 time faster in my trials but don't trust me, try it yourself)
Just faced this situation. Upgrading docker it is not an alternative. Even so, it is not a straight solution, but works:
FROM ${IMAGE:-my-image} ARG NAME # I have already created a 'simple-user' and already inside its user's directory RUN mkdir dependencies # Here is the simple trick, switch to root USER root # Do the copies (no --chown flag required) COPY ./dependencies/a ./dependencies/a COPY ./dependencies/b ./dependencies/b COPY ./dependencies/c ./dependencies/c COPY ./dependencies/d ./dependencies/d # It is time for admin performing all necessary modifications RUN chmod -R +x ./dependencies/*.sh # Variable substitution will work gracefully here, so root will delivery the directory ownership to the original 'simple-user' RUN chown -R ${NAME}:${NAME} ./dependencies/* # Switch back to 'simple-user' and continue doing the rest of the job USER ${NAME}What do you mean by "switch to root"? you are already root by default. And
COPYdidn't honorUSERcommand (not sure if it does now). Anyway,COPY --chown ...is several times faster thanRUN chown ...(as in, more than 10 time faster in my trials but don't trust me, try it yourself)
In my case, with my Dockerfile flow, the command executions are performed by a not root user. I do this because I am preparing an image with Elasticsearch and root can not execute it by default for security reasons. In this way, I saw myself obligated creating a simple user (firstly as root), and then continuing all the flow as a simple user. The issue occurs when I try to copy something from host to the image as simple user. In the end, I need to switch back in the flow as root, perform the copies, give the due permissions to the simple user over the files and come back with him. As I said before, this is not a straight solution, just a way. Best regards.
Do you happen to have any restriction in terms of docker version in your
working environment?
Le lun. 30 sept. 2019 à 13:09, iktuz notifications@github.com a écrit :
Just faced this situation. Upgrading docker it is not an alternative. Even
so, it is not a straight solution, but works:FROM ${IMAGE:-my-image}
ARG NAMEI have already created a 'simple-user' and already inside its user's directory
RUN mkdir dependencies
Here is the simple trick, switch to root
USER root
Do the copies (no --chown flag required)
COPY ./dependencies/a ./dependencies/a
COPY ./dependencies/b ./dependencies/b
COPY ./dependencies/c ./dependencies/c
COPY ./dependencies/d ./dependencies/dIt is time for admin performing all necessary modifications
RUN chmod -R +x ./dependencies/*.sh
Variable substitution will work gracefully here, so root will delivery the directory ownership to the original 'simple-user'
RUN chown -R ${NAME}:${NAME} ./dependencies/*
Switch back to 'simple-user' and continue doing the rest of the job
USER ${NAME}
What do you mean by "switch to root"? you are already root by default. And
COPY didn't honor USER command (not sure if it does now). Anyway, COPY
--chown ... is several times faster than RUN chown ... (as in, more than
10 time faster in my trials but don't trust me, try it yourself)In my case, with my Dockerfile flow, the command executions are performed
by a not root user. I do this because I am preparing an image with
Elasticsearch and root can not execute it by default for security reasons.
In this way, I saw myself obligated creating a simple user (firstly as
root), and then continuing all the flow as a simple user. The issue occurs
when I try to copy something from host to the image as simple user. In the
end, I need to switch back in the flow as root, perform the copies, give
the due permissions to the simple user over the files and come back with
him. As I said before, this is not a straight solution, just a way. Best
regards.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/moby/moby/issues/35018?email_source=notifications&email_token=AATR7L2R4A62B2ZFPD22WITQMHM7JA5CNFSM4D44U4L2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD75I4KI#issuecomment-536514089,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AATR7L5WARB32MDC7BXBDL3QMHM7JANCNFSM4D44U4LQ
.
Just for now. Version upgrade is strongly considered for sure.
I'm on 19.03.3 and I still face this issue.
@ahallur could you please a test case?
I've the exact same issue as the OP has. .
I've the following in my Dockerfile
ARG USER=user
ARG GROUP=group
COPY --chown=${USER}:${GROUP} /path/to/my/main.py .
When I try to build it, it fails with the error message. .
unable to convert uid/gid chown string to host mapping: can't find uid for user ${USER}: no such user: ${USER}
Also I'm running an up to date docker version
$ docker version
Client: Docker Engine - Community
Version: 19.03.3
API version: 1.40
Go version: go1.12.10
Git commit: a872fc2
Built: Tue Oct 8 00:55:12 2019
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.3
API version: 1.40 (minimum version 1.12)
Go version: go1.12.10
Git commit: a872fc2
Built: Tue Oct 8 01:01:15 2019
OS/Arch: linux/amd64
Experimental: true
containerd:
Version: v1.2.10
GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339
runc:
Version: 1.0.0-rc8+dev
GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
docker-init:
Version: 0.18.0
GitCommit: fec3683
It builds fine if I hardcode the user and group.
Yeah, you need to firstly have the user and group
I've the exact same issue as the OP has. .
I've the following in myDockerfileARG USER=user ARG GROUP=group COPY --chown=${USER}:${GROUP} /path/to/my/main.py .When I try to build it, it fails with the error message. .
unable to convert uid/gid chown string to host mapping: can't find uid for user ${USER}: no such user: ${USER}Also I'm running an up to date docker version
$ docker version Client: Docker Engine - Community Version: 19.03.3 API version: 1.40 Go version: go1.12.10 Git commit: a872fc2 Built: Tue Oct 8 00:55:12 2019 OS/Arch: darwin/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.3 API version: 1.40 (minimum version 1.12) Go version: go1.12.10 Git commit: a872fc2 Built: Tue Oct 8 01:01:15 2019 OS/Arch: linux/amd64 Experimental: true containerd: Version: v1.2.10 GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339 runc: Version: 1.0.0-rc8+dev GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 docker-init: Version: 0.18.0 GitCommit: fec3683It builds fine if I hardcode the user and group.
Could you please provide a complete Dockerfile?
Tried to run it, it turns out to be working fine
I tried the same for ADD and it doesn't work either:
ARG AS_OS_USER=user
ARG AS_OS_USER_GROUP=group
ADD --chown=${AS_OS_USER}:${AS_OS_USER_GROUP} 03-as-preconfig.sh ./
unable to convert uid/gid chown string to host mapping: can't find uid for user ${AS_OS_USER}: no such user: ${AS_OS_USER}
But using the same user and group directly works:
ADD --chown=user:group 03-as-preconfig.sh ./
Note that I use the same ARGs elsewhere in the Dockerfile (RUN, USER) and they work there alright.
docker version
Client: Docker Engine - Community
Version: 19.03.5
API version: 1.40
Go version: go1.12.12
Git commit: 633a0ea
Built: Wed Nov 13 07:25:41 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.5
API version: 1.40 (minimum version 1.12)
Go version: go1.12.12
Git commit: 633a0ea
Built: Wed Nov 13 07:24:18 2019
OS/Arch: linux/amd64
Experimental: true
containerd:
Version: 1.2.10
GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339
runc:
Version: 1.0.0-rc8+dev
GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
docker-init:
Version: 0.18.0
GitCommit: fec3683
Copy works, add does not. It could be interesting to have it also in ADD, as it provides some capabilities that copy does not provide
^ Confirmed COPY working, but ADD not. I switched to COPY since I use a local content at that place.
I think variable expansion should be implemented for the Dockerfile
--optionsin general (so not just for--chown)
anyone already working on this? If not, I'm interested to implement it
It seems that the variable is not always expanded in the same way, that is probably why this requirement is associated to a specific keyword. To see if it could be achievable with a non invasive modification.
Most helpful comment
This is fixed on master now through https://github.com/moby/buildkit/pull/926, and https://github.com/moby/moby/pull/39132;
Build the dockerfile, once without a build-arg (to use the default
onegrp/oneusr), and once with:Run the images to see that the user/group was set accordingly: