-
Notifications
You must be signed in to change notification settings - Fork 489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
docker-container driver: COPY --link --chown
unexpectedly changes parent dir ownership
#1855
Comments
My guess here would be that because FROM scratch
COPY ...... And here the "chown" affects the parent directories because But perhaps @jedevc or @tonistiigi could back that theory |
@tonistiigi mentioned these in the past:
In the meantime, it may be a gotcha worth documenting? Existing parent paths will need an extra |
For clarity the
UPDATE: Full overview documented here. Versions info at end of comment. TL;DR: Skip remainder of this comment, follow-up provides reproduction example where ObservationsThe docs for
Given those observations:
I have observed that if I had permissions such as
However... when I added I'll provide a comment after this one with insights for this. Reproduction versionsStill reproducible with Docker Engine $ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT
con* docker-container
\_ con0 \_ unix:///var/run/docker.sock running v0.15.2
default docker
\_ default \_ default running v0.13.2 NOTE: Using $ docker info
Client:
Version: 26.1.1
Context: default
Debug Mode: false
Plugins:
buildx: Docker Buildx (Docker Inc.)
Version: v0.14.0-desktop.1
Path: /usr/local/lib/docker/cli-plugins/docker-buildx
compose: Docker Compose (Docker Inc.)
Version: v2.27.0-desktop.2
Path: /usr/local/lib/docker/cli-plugins/docker-compose
#...
Server:
# ...
Server Version: 26.1.1
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: false
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: e377cd56a71523140ca6ae87e30244719194a521
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: unconfined
Kernel Version: 5.15.123.1-microsoft-standard-WSL2
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64 |
The Summary:
Does Reproduction
# syntax=docker.io/docker/dockerfile:1
FROM alpine AS base
RUN apk --no-cache add eza
CMD eza -lanhog --tree --no-time --no-filesize --no-permissions /foo
# Base permissions and ownership: `777 100:100`
FROM base AS src
WORKDIR /foo/bar/baz
RUN <<HEREDOC
touch a b c
chown -R 100:100 /foo
chmod -R 777 /foo
HEREDOC
# Adjusts parent dirs permissions and ownership to: `770 200:200`
FROM base AS dest
RUN <<HEREDOC
mkdir -p /foo/bar/baz
chown -R 200:200 /foo
chmod -R 770 /foo
HEREDOC
# Variant stages that may adjust permissions to `700` or ownership to `300:300`:
# Parent dirs become `755 0:0`, unexpected `--link` behaviour with `docker-container` driver:
FROM dest AS bug
COPY --link --from=src /foo/bar/baz /foo/bar/baz
# Parent dirs become `755 300:300`, but they are expected to remain as `770 200:200`:
FROM dest AS with-chown
COPY --link --chown=300 --from=src /foo/bar/baz /foo/bar/baz
# Any value with `--chmod` will prevent the `--link` + `--chown` affecting parent segments:
FROM dest AS with-chmod
COPY --link --chown=300 --chmod=700 --from=src /foo/bar/baz /foo/bar/baz
# Fix? - Any invalid value for `--chmod` will work too (without actually altering permissions):
FROM dest AS with-chmod-fix
COPY --link --chown=300 --chmod=null --from=src /foo/bar/baz /foo/bar/baz
# When COPY target does not exist, the parent segments will default to `0755 root:root`, original src parents ignored.
# However `--chown` unexpectedly modifies the parent segments ownership to `0755 300:300`, while `--chmod` does not affect parents:
FROM dest AS without-dest-dir
RUN rm -rf /foo
COPY --link --chown=300 --chmod=null --from=src /foo/bar/baz /foo/bar/baz Optional shell script to run. Builds each stage variant, generating the output shown next: #!/bin/env bash
function run_example() {
local -A STAGES
STAGES['bug']="'--link':\n(unexpectedly modifies parents ownership and permissions)"
STAGES['with-chown']="'--link --chown=300':\n(same issue but ownership change is to '300' instead of '0')"
STAGES['with-chmod']="'--link --chown=300 --chmod=700':\n(with '--chmod' flag the parents permissions and ownership are no longer modified, but not enforces modifying source permissions)"
STAGES['with-chmod-fix']="'--link --chown=300 --chmod=null':\n('--chmod=null' preserves 'src' stage permissions, this is the desired outcome)"
STAGES['without-dest-dir']="'--link --chown=300 --chmod=null':\n(when parent dirs in 'dest' stage don't exist, '--chmod=null' understandably has no influence)"
# Iterate via deterministic order of keys:
local -a STAGE_KEYS=(bug with-chown with-chmod with-chmod-fix without-dest-dir)
for STAGE in "${STAGE_KEYS[@]}"; do
local OBSERVATION="${STAGES[${STAGE}]}"
echo -e "Stage(${STAGE}) ${OBSERVATION}"
# NOTE: `1>/dev/null` is used to silent irrelevant stdout outputs
docker buildx build --load --quiet --target "${STAGE}" --tag bug-copy-link . 1>/dev/null
docker run --rm --tty bug-copy-link
docker image rm bug-copy-link 1>/dev/null
echo -e '\n'
done
}
run_example Output from script:
No shell script: inputs preview + bug vs expected results# The source ownership and permissions:
$ docker buildx build --load --target src --tag bug-copy-link . && docker run --rm -it bug-copy-link
Octal User Group Name
0777 100 100 /foo
0777 100 100 └── bar
0777 100 100 └── baz
0777 100 100 ├── a
0777 100 100 ├── b
0777 100 100 └── c
# The destination ownership and permissions:
$ docker buildx build --load --target dest --tag bug-copy-link . && docker run --rm -it bug-copy-link
Octal User Group Name
0770 200 200 /foo
0770 200 200 └── bar
0770 200 200 └── baz
# `--link --chown=300` (with or without dest dir existing, but `--chmod=null` fix only works when dest dir exists):
$ docker buildx build --load --target without-dest-dir --tag bug-copy-link . && docker run --rm -it bug-copy-link
Octal User Group Name
0755 300 300 /foo
0755 300 300 └── bar
0755 300 300 └── baz
0777 300 300 ├── a
0777 300 300 ├── b
0777 300 300 └── c
# Expected result:
$ docker buildx build --load --target with-chmod-fix --tag bug-copy-link . && docker run --rm -it bug-copy-link
Octal User Group Name
0770 200 200 /foo
0770 200 200 └── bar
0770 200 200 └── baz
0777 300 300 ├── a
0777 300 300 ├── b
0777 300 300 └── c |
Contributing guidelines
I've found a bug and checked that ...
Description
Originally reported at BuildKit: moby/buildkit#3912
Scenario: Adding content from a different image on DockerHub via
COPY --link
, and correcting the ownership with--chown=<uid>
.When building with the
buildx
driverdocker-container
, the parent directories (/var/lib
) appear to also have had their ownership modified to the--chown
value.It's possible that this bug is related to how the feature(s) work when pulling an image from a registry, or when building an image locally with
--load
via thedocker-container
driver. The nativedocker
driver does not build images with this ownership bug.Expected behaviour
/var
and/var/lib
should not have their ownership changed since they already exist in the image, only/var/lib/clamav
was copied over.Actual behaviour
Parent directories ownership is changed from the
COPY --link --chown
.Buildx version
github.com/docker/buildx v0.10.4 c513d34
Docker info
docker info
Builders list
Configuration
Additional info
This bug seems potentially related to:
We do have these current releases where you can observe this by pulling from the registry:
mailserver/docker-mailserver:11.3.1
:Dockerfile
COPY --link
linemailserver/docker-mailserver:12.0.0
:Dockerfile
COPY --link
line with--chown=200
addedPulling the v12 image or anything newer has
/var
and/var/lib
with ownership ofclamav
/200
, when that should only apply from/var/lib/clamav
as per theDockerfile
.Originally we used
COPY --link
until realizing the UID/GID value mapping was not reliable, and that theclamav
user and group could not be used with--chown
with--link
, so we created the user explicitly before installing a package that would create aclamav
user/group, and reference that stable UID for--chown
: moby/buildkit#2987 (comment)The text was updated successfully, but these errors were encountered: