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 seluser
user.
What do I need to do to give seluser
the permission to write to a folder owned by 2100?
Thanks in advance.
Regards
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
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.