Docker user cannot write to mounted folder

2019-07-02 14:04发布

问题:

I have the following setup:

  selenium-chrome:
    image: selenium/node-chrome-debug:3.141.59-neon
    container_name: chrome-e2e
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
      - SHM-SIZE=2g
      - GRID_DEBUG=false
      - NODE_MAX_SESSION=1
      - NODE_MAX_INSTANCES=5
      - TZ=Europe/Brussels
    hostname: chrome-e2e
    networks:
      - build-network
    ports:
      - 5900:5900
    volumes:
      - ./target:/home/seluser/Downloads

Selenium tests are run inside the container, the actual test code is outside of the container. Using Maven we handle the lifecycle of the containers. As you can see I mounted the Chrome download folder (inside the container) to the target-folder of my application. All is mounted well but when Chrome tries to download a file, permission is denied to write to /home/seluser/Downloads. The UID and GID of /home/seluser/Downloads is set to 2100:2100 by Docker. Chrome itself is run via the seluseruser.

What do I need to do to give seluser the permission to write to a folder owned by 2100?

Thanks in advance. Regards

回答1:

Bind mounts in Linux do not perform any namespacing on the uid or gid, and host mounts are running a bind mount under the covers. So if the uid inside the container is different from the uid on the host, you'll get permission issues. I've worked around this in other containers with a fix-perms script. Implementing that looks like the following Dockerfile:

FROM selenium/node-chrome-debug:3.141.59-neon
COPY --from=sudobmitch/base:scratch /usr/bin/gosu /usr/bin/fix-perms /usr/bin/
COPY entrypoint.sh /entrypoint.sh
# use a chmod here if you cannot fix permissions outside of docker
RUN chmod 755 /entrypoint.sh 
USER root
ENTRYPOINT [ "/entrypoint.sh" ]

The entrypoint.sh looks like:

#!/bin/sh
if [ "$(id -u)" = "0" -a -d "/home/seluser/Downloads" ]; then
  fix-perms -r -u seluser /home/seluser/Downloads
  exec gosu seluser /opt/bin/entry_point.sh "$@"
else
  exec /opt/bin/entry_point.sh "$@"
fi

What's happening here is the container starts as root, and the fix-perms script adjust the seluser inside the container to match the uid of the /home/seluser/Downloads directory. The exec gosu then runs your container process as the seluser as the new pid 1.

You can see the code used to implement this at: https://github.com/sudo-bmitch/docker-base

I've discussed this method in several of my presentations, including: https://sudo-bmitch.github.io/presentations/dc2019/tips-and-tricks-of-the-captains.html#fix-perms



回答2:

You can create your own Dockerfile:

FROM selenium/node-chrome-debug:3.141.59-neon

VOLUME /home/seluser/Downloads

and the docker-compose.yml should be:

  selenium-chrome:
    build: .
    container_name: chrome-e2e
    depends_on:
      - selenium-hub
  ...

The VOLUME directive will create the directory with the current user (seluser in this case) so that Docker will not have to create it with a different user.



标签: docker