Moby: Proposal: Add --chmod flag to ADD/COPY commands (analogous to --chown)

Created on 12 Sep 2017  路  59Comments  路  Source: moby/moby

Description
I've bumped into #34263 being merged and it hit me that --chmod would be nice in conjunction with this feature.

I frequently build Linux images from a Windows machine and I'm kind of annoyed with the 755 mode the added/copied files end up with.

ADD/COPY with --chown and --chmod together will be a readable and maintainable notation delivering precise control over permissions.

I'm aware of #29853, but I don't think this issue is a duplicate (that one seems to be stale).

arebuilder kinfeature statuaccepted

Most helpful comment

Any update on this topic ?

All 59 comments

/cc @tonistiigi @AkihiroSuda @duglin

I got tons of Dockerfiles RUNning a chmod after a COPY or ADD, as I am not always confident in the execution rights of the files.

I'm personally ok with this; especially for the Windows case, I agree this makes a good addition. I'll bring this up in a maintainers meeting to get other opinions, but if a contributor wants to work on this, I think this would get accepted.

Discussing in the maintainers meeting, and we're okay with this proposal; we do need to design the syntax to be usable, and take into account that we probably want to have parity on Windows (both for --chown and --chmod); input / proposals for the would be welcome!

/cc @johnstep @tianon

w.r.t. Windows we can adopt Cygwin-like model:

  • owner is the one specified in --chown
  • ACL contains three entries for owner, group and everyone respectively covering rwx bits
  • SUID, SGID and sticky bits are not portable

-OR-

there can be Windows-specific syntax, e.g., we can specify security descriptor with SDDL
yes, such a notation is bulky and challenging, but it delivers precision and unambiguity
besides, people who manage file system permissions on Windows would better be aware of this syntax

This would indeed be a nice feature. A use case other than for Windows is when one wants to build a image that can be run as arbitrary non-root user via the docker --user option. In this case, chmod has to be used after COPY to give group read/write permission (assuming group ID is set to 0 via chown). This unfortunately invalidates the layer and makes the resulting image bigger.

@thaJeztah
I implemented the proposed chmod flag: https://github.com/moby/moby/pull/36123
Waiting for it to be reviewed

I'm facing an issue with permissions; I'm ADDing a .tgz file from an URL to an image, which is built FROM scratch, after some inspection i found out once the file is ADDed the binary into it ends up with -rw------- permissions.

Tried to build the image with a multi-stage Dockerfile, it ADDs the .tgz file, grants +x permissions and then the binary is copied to the FROM scratch stage, for some reason it shows exec format error when running the resulting image.

@ulm0 Not 100%, but that sounds familiar, and I think it could have been that the binary is not staticly compiled. And since you're running FROM scratch, the libraries it links against aren't present.

Here is a worked example from my own repo for doing it with golang: https://github.com/0xdevalias/docker-gobuster/blob/master/Dockerfile#L6

@0xdevalias the binary is built using musl, Copying the binary from a local folder works, but using ADD breaks the image, I'm using another approach, this is the Dockerfile I'm using now so i can put this in a CI pipeline

FROM alpine:edge

RUN wget --quiet https://binaries.cockroachdb.com/cockroach-v1.1.6.linux-musl-amd64.tgz -O /tmp/cockroach.tgz && \
    tar xvzf /tmp/cockroach.tgz --strip 1

FROM scratch
ENV COCKROACH_CHANNEL=official-docker
COPY ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=0 /cockroach /cockroach/cockroach

# This causes the binary within the tgz file to end up with 400 permissions in the /cockroach/ folder
# It throws a permission denied error when attempting to run 
# ADD https://binaries.cockroachdb.com/cockroach-v1.1.6.linux-musl-amd64.tgz /cockroach/cockroach

WORKDIR /cockroach/
EXPOSE 26257 8080
ENTRYPOINT ["/cockroach/cockroach"]

Any update on this topic ?

This being postponed pending moby/buildkit#396. Basically there's major rewrite of the build engine going on. So the current engine is on feature freeze.

Will the caching behavior here be similar to how --chown works? It looks to me after some local testing that the target ownership is part of the caching strategy, not the build context ownership.

For example:

  1. Dockerfile

    FROM alpine@sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
    
    RUN addgroup -g 1500 delivery \
        && adduser -G delivery -D -u 2000 pizza
    COPY --chown=pizza:delivery file.txt /tmp/chowned-file.txt
    
  2. touch file.txt && chown mkobit:mkobit file.txt

  3. docker image build -t "${PWD##*/}" --iidfile before.iidfile .

    docker-copy-exploration > docker image build -t "${PWD##*/}" .
    
    Sending build context to Docker daemon  3.072kB
    Step 1/3 : FROM alpine@sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
     ---> 196d12cf6ab1
    Step 2/3 : RUN addgroup -g 1500 delivery     && adduser -G delivery -D -u 2000 pizza
     ---> Running in 4dac232d1f55
    Removing intermediate container 4dac232d1f55
     ---> a9964e7c0f90
    Step 3/3 : COPY --chown=pizza:delivery file.txt /tmp/chowned-file.txt
     ---> d92fedffdc8d
    Successfully built d92fedffdc8d
    Successfully tagged docker-copy-exploration:latest
    
  4. chown docker:docker file.txt

  5. docker image build -t "${PWD##*/}" --iidfile after.iidfile .

    docker-copy-exploration > docker image build -t "${PWD##*/}" --iidfile after.iidfile .
    
    Sending build context to Docker daemon  3.072kB
    Step 1/3 : FROM alpine@sha256:621c2f39f8133acb8e64023a94dbdf0d5ca81896102b9e57c0dc184cadaf5528
     ---> 196d12cf6ab1
    Step 2/3 : RUN addgroup -g 1500 delivery     && adduser -G delivery -D -u 2000 pizza
     ---> Using cache
     ---> a9964e7c0f90
    Step 3/3 : COPY --chown=pizza:delivery file.txt /tmp/chowned-file.txt
     ---> Using cache
     ---> d92fedffdc8d
    Successfully built d92fedffdc8d
    Successfully tagged docker-copy-exploration:latest
    
  6. compare image Ids (output above shows they are the same and caching the same, but just for completeness)

    docker-copy-exploration > cmp --silent before.iidfile after.iidfile
    docker-copy-exploration > echo $?
    0
    

Will the same type of behavior be true for chmod?

Who knows. This proposal is postponed. See ^^^.
But, actually, I don't see any issue. From docs:

All new files and directories are created with a UID and GID of 0, unless the optional --chown flag specifies a given username, groupname, or UID/GID combination to request specific ownership of the content added.

Given this, owner in the build context is absolutely irrelevant for build process.

Still, it requires in container available tooling to set UID and GID or use a ridiculous multi-stage build as described above. The feature freeze blocker is resolved - do we see some update on this now?

Any update on this topic ?

I want this.

@reporter123 seems like https://github.com/moby/buildkit/issues/396 is closed, can this get picked up again?

Any ETA?

This would be such a great move - it really makes sense to do this!

For sake of neutrality, I propose a platform-agnostic model

--owner=[uid/SID]
--executable=[true/false] (ignored in Windows containers as Win doesn't support the concept of executables)
--acls=[Unix chmod/Windows ACLS] (platform-dependent)

Most of the times, according to community, one needs just to ensure the file is executable. Using COPY --executable=true someFile.script destination.script achieves chmod effect but has no additional effect on Windows. Should new platforms be made with different concepts of _executable_, the directive will be honored by Docker Engine.

If one needs fine grained control over chmod, they may use --acls taking into account the effective platform. For Windows containers, it will enable Windows ACLs which are kind of complex compared to simple chmod

@djechelon Unfortunately, there are counter-arguments.
The syntax you propose adds three platform-dependent fields that are marketed as platform-agnostic.
I don't buy it, really.

  • --executable is redundant because --acls already specifies if file is to be executable (moreover, how to resolve conflicts between these two fields?)
  • --owner naming is also hard to sell as --chown already exists and maps almost fine for Windows (almost because on Windows a security group can own objects)

There is almost zero interest towards this feature, but after 2+ years of deliberation I tend to believe that file-system permissions are inherently not portable between Linux and Windows. It's not constructive to consider portability of inherently non-portable stuff a show-stopper.

What may work (almost repeating myself from September 2017):

  • Implement --chown and --chmod in a straightforward way on Linux
    and behave like Cygwin on Windows
  • Either don't bother supporting permission fine-tuning on Windows or just use SDDL notation.

There is almost zero interest towards this feature

From who? I'd really like this feature.

I propose --chmod syntax akin to rsync, which supports the usual chmod syntax plus you can restrict it to files or dirs like F440,D550.

I code on Windows but I don't really care about Windows support, there's too many other problems using straight Windows; just use WSL2 and everything is mostly great.

There is almost zero interest towards this feature

From who? I'd really like this feature.

Zero interest from the side of the developers, who would have to actually sit and write a few lines of code.

Which is totally unnecessary because every docker user has learned to simply create an extra layer to chmod added files (including switching to root and back, if necessary), but nobody cares about that extra computation power and image size anyway. And for hardware producers and nuclear plant operators it's a blessing, because you need to buy more.

@mnpenner rsync syntax is a great and compatible refinement, great idea!
(Even though it's more for the sake of completeness rather than for the benefit of real use cases.)

@llech some time after me stumbling upon this issue, I've switched to fine-tuning in RPM rather than in Dockerfile. Multi-stage builds also address some extraneous layers issues. Doing chmod not in Dockerfile but somewhere else actually enhanced my overall user experience.
Realistically, Dockerfile undoubtedly allows to do stuff beyond Hello World, but sometimes it's not the right tool for the job.

@mnpenner @djechelon Yes, the initial issue was because of building a Linux containers from Windows and being unable to make a script executable automagically based on permission bits in checkout. (Having to track executable bits for Git annoyed me some time ago until I wrote a script that does git update-index --chmod=+x for any file with a shebang.)

But neglecting Windows is not an option. It's a robust and scalable system quite on par with Linux if handled properly. (Why it's almost never handled properly is not a politically correct topic as it upsets some incapable ops people.) There are features unique or better implemented in Linux and vice versa.
Windows Containers did bring some cash to Docker, Inc. so their wish not to introduce Linux-only features is kind of understandable.
On the other hand, the hype around Docker-based perception of containerization distorted Windows Server as a product and it's Docker that prevented rapid container adoption on Windows. If I'm not clear enough, think about this: there is no viable LXC-style solution for Windows whereas ops people on Windows side are kind of predisposed to system containers, not app containers.
Parallels/Virtuozzo Containers for Windows used to fill the niche, but Microsoft made it impossible to carry this solution beyond Windows Server 2012. (I concur with Microsoft in their reasoning, but I'm sad about it anyway. Full disclosure: I'm a former Parallels/@Virtuozzo developer.)

Not a good place to rant about Windows, but, like I said, the issue is Windows-related.

it's Docker that prevented rapid container adoption on Windows

This blog post from 2016 begs to differ: https://www.docker.com/blog/docker-microsoft-partnership/. Also, that rant was off topic maybe?

@sirlatrom Are you offended? Oh, you're a Docker Captain, I completely feel for you.

Yet, do you understand that your link not only doesn't contradict my point, but illustrates it?
A person familiar and involved with the subject in circa 2015--2017 would remember that initially (in Windows Server Technical Previews) there were system containers even capable of running Remote Desktop sessions containerized. I.e. the design used to be LXC-like. Then the mentioned Docker/Microsoft partnership had been struck and suddenly Windows Containers were stripped down to bare bones minimally required to support Docker application container vision. Coincidence, of course.
A great deal of Win32 and COM APIs interact with core user-space services, but e.g. LanmanServer is crippled and disabled and LanmanWorkstation is not fully functional.
As a result, there is no practical lift-and-shift for existing Windows workloads, whereas re-engineering a, say, .NET application toward .NET Core creates an opportunity to embrace Linux instead of Windows.
Plus, the concept of ephemeral containers still doesn't fit the way ops guys operate in real world. I do fail to comprehend a win-win scenario here.
(Full disclosure: once upon a time I've assessed feasibility of containerizing a proprietary ASP.NET application. I don't argue that the application was a model one, but it's definitely several order of magnitude more complicated/useful than 'Hello World'-style apps used in lift-and-shift marketing demos.)

Yet, the Docker support for Windows seems to haunt this proposal.

Phew! What is really off topic:

  • trying to enforce semantic portability of file-system permissions across dissimilar permission models.
    Would be nice, but for Windows the silver bullet is SDDL (not heard on Linux) and every attempt to apply Unix-style conventions would be an approximation. Cygwin have devised a good enough one, though.
  • attempting to down-size the issue to execution permission tracking for painless builds from Windows clients.
    It's not tracked in build context from Windows side, so it's a natural idea to track it in build directives the same way as --chown.
    BUT it boils down to Docker Engine issuing chmod(2). A user-friendly convention/syntax for Dockerfile could be based on

    • either chmod(1) from coreutils (familiar to any competent console-friendly Linux admin)

    • or rsync's --chmod (downward-compatible with chmod(1) style; thanks again @mnpenner).

  • arguing that WSL2 will fix all the cross-platform pains from Windows side of the issue.
    The life will be better, but it won't fix everything unless you move your IDE inside a WSL2 container distro. Visual Studio Code nailed it, but it's unlikely that other major players will follow the suit.
  • talking conspiracy theories like this:

And for hardware producers and nuclear plant operators it's a blessing, because you need to buy more.

This is a proposal thread and it implies discussion. Following up emerging arguments is fine. So is disproving other people's points.

FWIW, I'm using PhpStorm with a project mounted under \\wsl$ and the performance seems reasonable. They have a ticket to add better support, so hopefully they will or MS will keep improving the interop.

I'm not familiar with this SDDL but sounds alright. Maybe Docker can add --chmod and --sddl as part of a separate change? I don't think these flags need to be cross-OS anyway, everything you put in the Dockerfile already depends on the container OS, no?

Really strange that this feature isn't already implemented!

Hello..

Supplementary argument for this feature request :

The only way of changing permissions after COPY commands is to RUN chmod -R ..... on the copied files.
This adds a new layer that has the same size as the copied files which practically double the final image size !

Doing some permission management is required for some usage like running Docker images in Openshift (Kubernetes) : https://docs.openshift.com/container-platform/3.3/creating_images/guidelines.html#use-uid

This cost us terabytes of disk for nothing.

Thanks

Another more generic option is running a command without creating a new layer (auto squashing with the previous layer). Then we don't really need all these hacky flags.

Another more generic option is running a command without creating a new layer (auto squashing with the previous layer). Then we don't really need all these hacky flags.

Try that on a scratch image.

I'm also running into this where some files do not have the right permissions and we can't change it during the COPY command, and have no choice but to add a second RUN command and double the image size. Hard to believe this was first brought up in 2017.

Try that on a scratch image.

Nonetheless, @bundabrg's suggestion would be helpful for tons of people.

If COPY --chown is supported, so should be --chmod

As a workaround for people who value image size (since there obviously isn't any traction on this issue), you can use multi-stage builds to add and "pre-chmod" your files in a temp image and then use COPY to copy them to the final image, permissions and all.

Tested on Docker CE 19.03.5 on Linux. I don't use Docker for Windows so I can't confirm if it works there.

For example with the following Dockerfile:

# Use an image with `chmod`
FROM alpine
ARG DUPLICACY_URL="https://github.com/gilbertchen/duplicacy/releases/download/v2.5.1/duplicacy_linux_x64_2.5.1"

# Add and chmod any files you want
ADD $DUPLICACY_URL /duplicacy
RUN chmod +rx /duplicacy

# Final image goes here
FROM alpine

# Copy from above temp image to final location
COPY --from=0 /duplicacy /usr/local/bin/duplicacy

ENTRYPOINT ["duplicacy"]

Results in:

image

Compared with the ADD/COPY + RUN chmod pattern:

image

```

Final image goes here

FROM alpine
```

Assuming you mean FROM scratch here?

# Final image goes here
FROM alpine

Assuming you mean FROM scratch here?

Up to you. In my case I wanted alpine in my final image.

In my case I wanted alpine in my final image.

That's literally the same as

FROM alpine

RUN set -eux; \
        wget -qO /usr/local/bin/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v2.5.1/duplicacy_linux_x64_2.5.1; \
        chmod +rx /usr/local/bin/duplicacy

ENTRYPOINT ["duplicacy"]

However, this is a perfect example why we need --chmod for FROM scratch images.

After all this discussion, I want to try to change my perspective.

Today, the --squash option is just experimental. I think that it should become the de facto standard in Docker images.

Squashed images present the smallest size compared with any other layered image.

Rather than smashing our heads about additional copy options, platform-neutral ACLs and what is the correct way to handle scratch images, falling "back" to squash everything could be more helpful.

You can just run both commands and have the final image squashed into a single layer.

Squash allows to make an image consist of a very single layer on top of its base image.
I don't know about a single Docker Hub image benefitting from any single intermediate image.
A number of open packages install software using apk or apt-get. But really, those intermediate images don't necessarily add value. What you want when you download an image is the final image.

If it's correctly engineered over an existing base image (e.g. a simple Alpine over a more complex LAMP stack) you will really benefit from the tagged intermediate images

Example: Tomcat is made on top of Alpine, and what the image needs to contain is just Tomcat. To install Tomcat, the authors install wget and pgp on top of Alpine, but no "Alpine with wget and pgp" image is available.

And for the Tomcat example, there are a number of flavours (8.5, 9.0... based on JDK 8 or 11, based on Alpine or a larger image...), so layered images do not provide any additional benefit. You still need to pull different base images.

My 0.000000000002 cents

I guess multilayer would still be important for storage efficiency ?

@pptime Multilayer storage is efficient when you reuse (intermediate) layers. I know about reuse of images (final layers) than intermediate.

Let's take a look from another angle: developer productivity.
All the dirty workarounds proposed do create additional storage layers, yet they're eliminated by the time it comes to final distribution.
But all of them still require some additional amount of I/O during build and developers might do a lot of rebuilds daily, depending on whether a developer uses Docker for real work and not for packaging only.

Implementing --chmod should be simple. Yet, it's still not done.
I believe, further discussion is counter-productive and futile.
Please, take a look at different container build tools or implement your own.
There exists #36123 and there's also some similar, yet much shorter drama in the comments. If you consider forking Docker for your own needs, this is a starting point.

As for my grievances about Docker (which extend far beyond this single proposal), at the moment I don't use Docker extensively, so I personally opt to do nothing.

Yes I agree, we use Docker as part of our continuous integration pipelines, and executing a supplementary chmod -R on big directory structures is also I/O and time consuming.

Some graphdrivers don't create this kind of excessive I/O: DM and ZFS, probably Btrfs also.
There are, however, a whole host of difficulties and inconveniences with them.

As for overlay2 (the current ubiquitous default), the issue may be partially mitigated in recent Linux kernels, see this PR merged around August 2018.
Yet, I'm not sure if this really effectively accelerates chmod -R by metadata-only copy-up.
And this overlay trickery definitely doesn't eliminate extra layers and doesn't make images slimmer when pushed to a registry.

On the other hand, most people use Ubuntu 18.04 an 16.04 on build hosts and are unlikely to jump to 20.04 soon. As for RHEL/CentOS world, EL8 kernel contains at least some of this functionality back-ported -- as it's not mentioned in the docs directly, it may work and it may not.

Still, a simple flag would be much more productive than delving into the kernel stuff.

In my case I wanted alpine in my final image.

That's literally the same as

FROM alpine

RUN set -eux; \
        wget -qO /usr/local/bin/duplicacy https://github.com/gilbertchen/duplicacy/releases/download/v2.5.1/duplicacy_linux_x64_2.5.1; \
        chmod +rx /usr/local/bin/duplicacy

ENTRYPOINT ["duplicacy"]

Sure, but it is just an example to demonstrate the workaround. That just happened to be one of the simpler Dockerfiles I had on hand to modify for an example.

Regardless of how unrealistic my example is, it still demonstrates a pattern that works for both remote and local files using only standard Dockerfile constructs. Whereas yours only works for remote files and also requires some knowledge of an external tool (ie wget, curl, etc). I don't see what you get out of nitpicking.

Can we add a new flag like --postcmd="chmod +x xxx". It let the user to do what they want.

In my situation, I'd like to setcap to the final target. Currently, I can only use RUN to add another layer to my image. If I have a postcmd in COPY, I can change these caps in one layer.

example:

FROM xxx
COPY --postcmd="setcap 'CAP_NET_BIND_SERVICE,CAP_NET_ADMIN,CAP_SYS_NICE,CAP_SYS_RESOURCE+eip' /example.exe" /path/to/target /example.exe 

I'd be happy to prototype an implementation if you guys think it is ok.

A more generic and useful idea is "explicit transaction control", i.e. layer boundaries are user-defined, so that a layer may contain side effects of multiple file-system operations. I wouldn't dare propose wording, though. Plus such a ~transgression~ radical deviation from initial simplistic Dockerfile design warrants creation of an independent build tool. It shouldn't be hard given docker cp, docker exec and docker commit already exist and do the hard stuff.
Otherwise, existing workarounds with multi-stage builds and squash exhibit similar "explicit transaction control" behavior and can be used instead.

As for setcap use case, I seriously doubt it's a great idea to start with. Docker doesn't support a notion of multiple capability sets (i.e. permitted, inheritable, effective, bounding and ambient) and container's PID1 starts with all the default capabilities plus ones added with --cap-add minus ones dropped with --cap-drop. Adding xattrs to executable binaries with setcap won't add effective capabilities unless they're already present in permitted set, and most likely the desired capabilities are already in place through inheritable set (unless dropped by a serious systemd-grade software, which is not welcome in Docker containers).
Since you need to explicitly define capability set on container creation, there is no need for setcap magic (unless you use "systemd-grade software", but it's a completely different story).

@unshare Thank you for your reply.

I have made a little change in buildkit to support --chmod option, and my colleague said he have a setcap use case, ask me to support it. I have little known about capabilities in docker, so I think setcap is Linux based command, maybe it 's better to let user to decide what to do with the copied file.

I know what you mean, I'll discuss with my colleague about his use case with setcap, thank you.

As I dig into this problem, I found it's really very interesting.

In our case, we are trying to run our program in docker with non-root user, but our program needs some capabilities such as SYS_NICE. If we don't set the file-cap, we can not enable these capabilities because docker sets pcaps +i instead of +eip in non-root user. I found a better way is to use the ambient capabilities, but right now, docker doesn't support ambient capabilities. I read the issues about ambient capabilities supported by docker. Maybe it's because of the suid problem that blocks this feature?

So, I really don't know what's the better way to do in our use case. (Sorry this is really not related to this proposal)

Sorry, I don't really understand the relationship between moby/buildkit and moby/moby and docker as documented on https://docs.docker.com/engine/reference/builder/#add. Is there an ETA on when this syntax will be available from dockerfiles using the docker command?

Docker v20 with this will be released within a few months

I'm using this feature as we speak, but I had to do some (not much) legwork beforehan and it was worth it.
BuildKit is a new build system that is mind-blowingly ahead of the regular Docker builder (which is feature-frozen for several years).
You can use BuildKit standalone, but it's also integrated with Docker for quite some time (you can replace the plain old builder with BuildKit by setting DOCKER_BUILDKIT=1 environment variable).
Or you can use buildx the Docker CLI plugin (version included in Docker Desktop lags behind, so check out releases from GitHub).
To enable --chmod right now, you need to explicitly specify Dockerfile parsing frontend (BuildKit has pluggable frontends).
The feature is already merged into master, so you may use docker/dockerfile-upstream repository from Docker (I believe, it's their CI output).
Add the following parser directive into the very top of your Dockerfile to activate (example):
syntax = docker/dockerfile-upstream:master-experimental
Of course, use it on your own risk, yada, yada.
FYI, I'm the original requestor and right now I'm more than happy with the execution on BuildKit side.
PS. Come on, BuildKit is not yet well-documented, but docs contain enough pointers to figure out everything I've just laid out and much more.

I can confirm that works great with BuildKit enable using env var DOCKER_BUILDKIT=1 and directive syntax = docker/dockerfile-upstream:master-experimental with the octal syntax of chmod eg: --chmod=744.
But it fails with classical alpha syntax --chmod=+x, --chmod="+x" or --chmod=o+x and --chmod="o+x" ...

Am I missing something or may be it's not supported yet ?

@finalspy The alpha syntax is for changing the permissions on an existing file (e.g. o+x means to set the execute bit to the "other" octet, leaving all other bits intact). What baseline permissions would you be changing from?

I could see an argument for supporting something like rwxr--r-- (equivalent of 744), but I don't think o+x offers clear enough semantics for a good implementation.

@jakerobb it's "other", not "owner".

You have a point regarging + and -, but what about e.g. a=rwx which is equal to u=rwx,g=rwx,o=rwx, which is same as 777?

@selurvedu thanks; corrected. I don't often use that syntax.

I was not familiar with the = option. That seems supportable.

The usefulness of alpha syntax usually comes from the capital X permission, which means "executable only if the file was previously executable or if it is a directory."

This is because a recursive COPY with --chmod=644 would make all directories non-executable, meaning non-traversable; while a --chmod=755 would make all files executable. Both are inappropriate therefore unuseable 99% of the time.

A recursive COPY with --chmod=u=rwX,go=rX (capital Xes) would set directories to 755 and files to 644, unless a given file already had the executable bit in the source filesystem, in which case it would get 755.

Personally, I think both syntaxes are cumbersome. I'd rather have a --umask setting, which is traditionally used to take away permissions., or maybe a UMASK top-level setting.

For example, --umask=022 would mean "not writable by group and others." This has the benefit of leaving the issue of executable files and/or traversable directories to Docker to figure out. Accordingly, --umask=077 would take away all rights except to the owner; --umask=0 would give everyone any available permissions; and so on.

This would probably be easier to adapt to Windows permissions, because it's a simpler specification.

Was this page helpful?
0 / 5 - 0 ratings