setfacl in Dockerfile has no effect
Asked Answered
O

1

7

I want to set the default acl for some folders when building a docker image using setfacl but it has no effect. The default acl is unchanged. My aim is that every file that is created in /opt must have rwX permissions for any user, as the image will be run with an arbitrary uid later and needs full access to /opt.

Here's a quick example Dockerfile

FROM ubuntu:bionic
SHELL ["/bin/bash", "-c"]
RUN apt-get update > /dev/null && apt-get install -y --no-install-recommends acl > /dev/null
RUN chmod -R a+rwXs /opt
RUN setfacl -d -m o::rwx /opt
RUN getfacl /opt

and the output is

# file: opt
# owner: root
# group: root
# flags: ss-
user::rwx
group::rwx
other::rwx

which is wrong, the default acl is missing. But if I run the commands in the container manually it works

docker run -ti --rm ubuntu:bionic bash
root@636bf8fdba41:/# apt-get update > /dev/null && apt-get install -y --no-install-recommends acl > /dev/null
debconf: delaying package configuration, since apt-utils is not installed
root@636bf8fdba41:/# chmod -R a+rwXs /opt
root@636bf8fdba41:/# setfacl -d -m o::rwx /opt
root@636bf8fdba41:/# getfacl /opt
getfacl: Removing leading '/' from absolute path names
# file: opt
# owner: root
# group: root
# flags: ss-
user::rwx
group::rwx
other::rwx
default:user::rwx
default:group::rwx
default:other::rwx

Any idea why docker does not correctly apply the acl changes when running setfacl in the Dockerfile?

Docker version 19.03.5, build 633a0ea838 Ubuntu 18.04 as host

Orlando answered 26/11, 2019 at 2:54 Comment(2)
I solved my problem with a different approach, but since it's not the answer to my acl question I post it as a comment rather than an answer: I set the umask to 0000 before every command I run in the Dockerfile. Looks nasty but allows any uid that connects to the docker container to install new packages with conda/pip. So basically: RUN umask 0000 && <any command> If someone knows a better solution, let me know!Orlando
Slight improvement to your solution: set custom SHELL at the begging of the Dockerfile so every RUN command will be prepended with umask 0000. Example: RUN printf '#!/bin/sh\numask 0000\n/bin/sh -c "$*"' | sudo tee /bin/umasksh && sudo chmod +x /bin/umasksh SHELL ["/bin/umasksh"] RUN mkdir some_dir # umask 0000 will be called before mkdirSibie
B
2

Any idea why docker does not correctly apply the acl changes when running setfacl in the Dockerfile?

Don't take this as an authoritative answer, because I'm just guessing.

Docker images have to run on a variety of distributions, with different storage backends (possibly even more when you facter in image registries, like hub.docker.com). Even those that are filesystem based may be backed by different filesystems with different capabilities.

This means that in order for Docker images to run reliably and reproducibly in all situations, they have to minimize the number of extended filesystem features they preserve.

This is probably why the extended attributes necessary to implement filesystem ACLs are not preserved as part of the image.


It works in a container because at this point the files are stored on a specific local filesystem, so you can take advantage of any features supported by that filesystem.

Buitenzorg answered 26/11, 2019 at 3:54 Comment(1)
Thanks for the guess. I just found that if I chain setfacl and getfacl then the correct acls are shown. So docker discards? resets? the acl after each command in the Dockerfile. Maybe you're right that acls are not preserved in the images but work in containers. Let's hope someone has an idea how I can achieve my goal, as simply running chmod a+rwX in the end increases my actual image from 7 GB to 18 GB...Orlando

© 2022 - 2024 — McMap. All rights reserved.