Skip to content
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

Permissions not inheriting #67

Closed
bigteejay opened this issue Nov 30, 2018 · 14 comments
Closed

Permissions not inheriting #67

bigteejay opened this issue Nov 30, 2018 · 14 comments

Comments

@bigteejay
Copy link

I dont know if the issue I am encountering is related to this or not.

I have a Dockerfile in which I ensure a path I want composer to install packages to has the needed permissions (specifically, that it is writable). However, rather than inheriting the permissions (with +s set), everything composer installs is read-only. Adjusting the Dockerfile to then go back and manually make things writable extends build times significantly (I killed it off at 20mins last time.)

Any idea as to what might be preventing the permissions from inheriting? Ideas for a viable workaround?

@alcohol
Copy link
Member

alcohol commented Nov 30, 2018

Not a clue unless you can provide me/us with a reproducible scenario :-)

@bigteejay
Copy link
Author

Completely fair. I'll see if I can mock up a repro shortly.

@bigteejay
Copy link
Author

./docker-compose.yml

version: '3.7'

services:
  prep-src:
    build:
      context: './prep-src/'
    volumes:
      - src:/var/www/html:rw
      
volumes:
  src: {}

./prep-src/Dockerfile

FROM composer

ARG BUILD_PATH=/var/www/html
RUN echo "NOTE: Using ${BUILD_PATH} for build path"
RUN mkdir -p ${BUILD_PATH} && cd ${BUILD_PATH}
WORKDIR ${BUILD_PATH}
RUN chown root:www-data ${BUILD_PATH} \
    && chmod u+rwxs,g+rwxs ${BUILD_PATH}

ARG TAO_CODE_TAG=v3.2-rc02
ADD --chown=root:www-data https://cdn.jsdelivr.net/gh/oat-sa/package-tao@${TAO_CODE_TAG}/composer.json ${BUILD_PATH}/composer.json

RUN composer install --ignore-platform-reqs --no-scripts --no-suggest --no-dev

# RUN chown -R root:www-data ${BUILD_PATH} \
    # && chmod -R u+rwxs,g+rwxs ${BUILD_PATH}

# Don't attempt to install via composer again, just exit
ENTRYPOINT 'sh'
CMD ''

So, if that last chmod (which takes quite a bit of time given the number of files it had to amend in the layer) is omitted, it runs pretty quickly. However, in spite of the parent permissions being set above, none of the files written by composer are writable.

You can then test the image built by... (probably self-explanatory, but just in case and for any others)

docker-compose up --build
docker image ls
docker run --rm -it [image reference] sh

Starts off in BUILD_PATH...

cd ..
ls -la

Note, ./html is writable

cd html
ls -la

...but folder contents written by composer are not writable by group (www-data, the apache user/service)

Make sense? I gotta step out for the evening, but can check in later.

@alcohol
Copy link
Member

alcohol commented Dec 3, 2018

Your mount completely invalidates the preparations you make in your Dockerfile for that path.

The first time you spin up your container using docker-compose, the named src volume will be created and owned by root. It will be mounted on top of /var/www/html. It will not inherit any of the permissions and such you set on it in your Dockerfile.

@bigteejay
Copy link
Author

bigteejay commented Dec 3, 2018

But it is mounted rw?

Also, why then does the parent ($BUILD_PATH) directory retain its permissions as defined in the Dockerfile (namely, u+w,g+w)?

Also, I commented out the line that calls composer, and uncommented the latter chmod command in the snippet above, then when I sh into it, the permissions were retained.

In my full project (which also has apache, php-fpm, and mysql), when I sh into the resulting containers, the files not created by composer also retain their writable permissions (it is only the files created by php composer from the image that do not, unless I force it in the Dockerfile, which is prohibitively time consuming, though functional.)

Hmm... actually (more to the point perhaps) the rest of the files (when I ADD them) should also retain/inherit the parent's permissions and I wouldn't have to manually adjust them either.

eg: ...


RUN chown root:www-data ${BUILD_PATH} \
    && chmod u+rwxs,g+rwxs ${BUILD_PATH}

ARG TAO_CODE_TAG=v3.2-rc02
ADD --chown=root:www-data https://cdn.jsdelivr.net/gh/oat-sa/package-tao@${TAO_CODE_TAG}/composer.json ${BUILD_PATH}/composer.json

Why doesn't the file resulting from the add statement reflect the permissions (with +s) set immediately above? I wonder if this is something in Docker itself (to minimize the changes/deltas per action/layer it in some way disables permission inheritance)?

Ugh.

PS: This could have interesting implications (for ADD/COPY specifically)

@alcohol
Copy link
Member

alcohol commented Dec 4, 2018

I'm just commenting on your example. You prepare a directory with certain permissions and such, and then you overlap a mount on top of it, creating a whole new directory structure basically. So I am not sure what you are expecting. The directory in the Dockerfile is not the same as you will have in the volume mount.

@bigteejay
Copy link
Author

Understood. I appreciate any feedback (relatively new to docker). That being said, it works as needed if I force +w in the image and mount as rw. I am just trying to figure out why the extra work is necessary and permissions arent just inherited from the parent folder.

@alcohol
Copy link
Member

alcohol commented Dec 5, 2018

I am rather confused as to what the problem is though. You say everything Composer installs is read-only. But what is 'everything'?

By default, the vendor directory (and all subdirectories) will be 755 and files will be 644, unless the original package explicitly maintains different permissions (those should be respected in most cases, especially since 5f82e6f).

These permissions are very suitable for almost all cases. If you want Composer to use different permissions though, you should probably just set a different umask before running Composer.

For example:

$ umask 0000
$ composer require ...
...

This will create directories with 777 permissions and files with 666.

@bigteejay
Copy link
Author

bigteejay commented Dec 6, 2018

"Everything" = the files in that image path (eg: /var/www/html) that are only present after build when the RUN composer install... line is NOT ccommented out.

(Still reviewing the rest of your feedback, just wanted to clarify that portion)

@bigteejay
Copy link
Author

Neither 755 nor 644 would be usable for my needs (as the application requires write permissions to the folder structure created by composer install ..., hence why my Dockerfile specifies +w)

Ah-ha! I am not familiar with umask, but that looks very promising (thanks)! I'll investigate using that tomorrow and see how it goes and let you know.

@bigteejay
Copy link
Author

I changed the Dockerfile to...

FROM composer

ARG BUILD_PATH=/var/www/html
RUN echo "NOTE: Using ${BUILD_PATH} for build path"
RUN umask u+rwx,g+rwx \
    && mkdir -p ${BUILD_PATH} && cd ${BUILD_PATH} \
    && chown root:www-data ${BUILD_PATH}
WORKDIR ${BUILD_PATH}

ARG TAO_CODE_TAG=v3.2-rc02
ADD --chown=root:www-data https://cdn.jsdelivr.net/gh/oat-sa/package-tao@${TAO_CODE_TAG}/composer.json ${BUILD_PATH}/composer.json

RUN composer install --ignore-platform-reqs --no-scripts --no-suggest --no-dev

RUN chown -R root:www-data ${BUILD_PATH}

# Don't attempt to install via composer again, just exit
ENTRYPOINT 'sh'
CMD ''

...but upon checking the outcome within the built image, the permissions are correct for the parent /var/www/html/, but still incorrect (no +w) for the contents therein.

Am I using it incorrectly?

@bigteejay
Copy link
Author

bigteejay commented Dec 8, 2018

Interestingly, docker runing into the created image, and just running umask yields 0022 as the current default (which seems unexpected?) But does match the permissions assigned to the folder contents (which I didn't expect since it doesn't match the only umask statement I supplied in the Dockerfile). Any ideas?

@jaapio
Copy link

jaapio commented Jan 27, 2019

I use this wrapper script to run the composer image:

#!/bin/bash

composer () {
    tty=
    tty -s && tty=--tty
    docker run \
        $tty \
        --interactive \
        --rm \
        --user $(id -u):$(id -g) \
        --volume $SSH_AUTH_SOCK:/ssh-auth.sock \
        --volume /etc/passwd:/etc/passwd:ro \
        --volume /etc/group:/etc/group:ro \
        --volume $HOME/.composer:/composer \
        --volume $(pwd):/app \
        --env SSH_AUTH_SOCK=/ssh-auth.sock \
        --env COMPOSER_HOME=/composer \
        --env APP_ENV=$APP_ENV \
        composer "$@"
}

composer "$@"

Using the --user param of docker you can specify running as a different user. Since linux is just using user id's and not usernames there is no need to create a user.

@alcohol
Copy link
Member

alcohol commented Jul 22, 2020

Closing this issue because there has not been any activity on it in a long time.

@alcohol alcohol closed this as completed Jul 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants