Chown breaks in bound volumes with Docker user namespace remapping: "Operation not permitted" - linux

I followed the instructions here for enabling user namespace remapping.
However, now inside of a container I can no longer change the ownership of a -v bounded volume.
I'm using Docker on Fedora with docker-compose. The volumes are bound like this:
service_name:
volumes:
- ./vol/service:/opt/service:Z
# other config info removed...
I tried adding cap_add:
service_name:
volumes:
- ./vol/service:/opt/service:Z
cap_add:
- CHOWN
- SETGID
- SETUID
# other config info removed...
That didn't help. The root user inside of the container cannot chown on the folder that's bound (in this example, /opt/service), or any of the contents inside of the folder, even when I ran chmod go+rwx vol/service on the host.
Help?

I needed to do two things to fix this problem:
I needed to remove the :Z on the volume binding
I needed to make sure that the permissions on the bound folder on the host started with the UID and GID found in /etc/subuid and /etc/subgid, respectively. In other words, I had to run (on the host): chown -R 100000:100000 vol/service

Related

Docker Bind Mount: error while creating mount source path, permission denied

I am trying to run the NVIDIA PyTorch container nvcr.io/nvidia/pytorch:22.01-py3 on a Linux system, and I need to mount a directory of the host system (that I have R/W access to) in the container. I know that I need to use bind mounts, and here's what I'm trying:
I'm in a directory /home/<user>/test, which has the directory dir-to-mount. (The <user> account is mine).
docker run -it -v $(pwd)/dir-to-mount:/workspace/target nvcr.io/nvidia/pytorch:22.01-py3
Here's the error output:
docker: Error response from daemon: error while creating mount source path '/home/<user>/test/dir-to-mount': mkdir /home/<user>/test: permission denied.
ERRO[0000] error waiting for container: context canceled
As far as I know, docker will only need to create the directory to be mounted if it doesn't exist already. Docker docs:
The file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist.
I suspected that maybe the docker process does not have access; I tried chmod 777 with dir-to-mount as well as with test, but that made no difference.
So what's going wrong?
[Edit 1]
I am able to mount my user's entire home directory with the same command, but cannot mount other directories inside the home directory.
[Edit 2]
Here are the permissions:
home directory: drwx------
test: drwxrwxrwx
dir-to-mount: drwxrwxrwx
Run the command with sudo as:
sudo docker run -it -v $(pwd)/dir-to-mount:/workspace/target nvcr.io/nvidia/pytorch:22.01-py3
It appears that I can mount my home directory as a home directory (inside of /home/<username>), and this just works.
docker run -it -v $HOME:$HOME nvcr.io/nvidia/pytorch:22.01-py3
I don't know why the /home/<username> path is special, I've tried looking through the docs but I could not find anything relevant.

Docker: mounting/sharing a single sock file?

I want to share php-fpm.sock between nginx and PHP. The way I've done this right now is like so:
services:
nginx:
build:
context: .
dockerfile: docker/nginx.docker
ports:
- '8080:80'
volumes:
- type: volume
source: php_fpm_sock
target: /mnt/sock
consistency: delegated
read_only: true
volume:
nocopy: true
links:
- php
php:
build:
context: .
dockerfile: docker/php.docker
links:
- mariadb
env_file: .env
volumes:
- type: volume
source: php_fpm_sock
target: /mnt/sock
consistency: delegated
read_only: false
volume:
nocopy: true
volumes:
php_fpm_sock:
i.e. I've moved the sock file from its usual location (/var/run/php5-fpm.sock) to /mnt/sock because I can't figure out how to mount a single file and I don't want to mount the whole /var/run dir.
Secondly, I've configured php-fpm as:
[www]
listen = /mnt/sock/php-fpm
;listen.owner = www-data
;listen.group = nginx
; php-fpm runs as `www-data`, nginx runs as `nginx`
listen.mode = 0664
i.e., I've given "other" full read privileges because the nginx user group doesn't exist in the php-fpm container so I don't know how else I can give permissions to just nginx.
This all feels pretty hacky. So my questions are:
How can I share just the sock file between these two containers so that I can move the sock file back to /var/run/php5-fpm.sock
How can I fix the read permissions on this file so that only nginx can read it? i.e. how can share linux user accounts across containers?
I can also add the nginx user into the php-fpm image,
RUN useradd -r -s /usr/sbin/nologin -c "Nginx service" -U nginx -u 101
And then I can set the permissions correctly. The UID must match between both images or it won't work so I've set it explicitly. If 101 had already been used for PHP I think I'd be in trouble again, so I don't love this solution either.
You kind of have to do it the way you show. (But mounting the volume over the PHP container's /var/run is probably fine.)
You have three big constraints here:
Mounts are mounting some external content into the container (which can be bidirectionally written to after startup), not publishing content out.
Docker mounts the volume into the container before the main container process starts, so whatever you're mounting must already exist.
The Compose dependency mechanism essentially enforces the order in which containers are created, but it won't wait for container processes to actually start.
So by the second constraint, you can't mount the PHP-FPM socket into the PHP container, because it doesn't exist yet when you're running docker-compose up. And by the third constraint, you can't mount the socket into the nginx container either, because it's not guaranteed to exist at the moment the container is created. (You can't mount single files out of named volumes either, but in theory you could work around this by bind-mounting a host directory.)
Since a container only runs a single process, there's probably nothing else in /var/run and by its nature it should be okay to hide everything there with an empty volume anyways. The only thing you might need to manually manage is a pid file.
How can I fix the read permissions on this file so that only nginx can read it? i.e. how can share linux user accounts across containers?
You need to manually ensure that the USER both containers are using have the same numeric user ID. Note that it's common (if discouraged) to run containers as root which will bypass any controls here anyways. There's no built-in way to do this.

inside container container file permission issue for non root user

I am extending a docker image of a program from here and I want to change some configs and create my own docker image. I have written a Dockerfile as follows and replaced the server.xml file in this image:
FROM exoplatform/exo-community
COPY server.xml /opt/exo/conf
RUN chmod 777 /opt/exo/conf/server.xml
When I created the docker image and run an instance from the image, the running program of the container cannot access the file server.xml because its owner is the root user and I see the permission denied error. I tried to change the ownership in the Dockerfile by chmod command but I see the Operation not permitted error. The user of the running container is not the root user and it cannot access the server.xml file that is owned by the root user. How can I resolve this issue?
If this is actually just a config file, I wouldn't build a custom image around it. Instead, use the docker run -v option to inject it at runtime
docker run \
-v $PWD/server.xml:/opt/exo/conf/server.xml \
... \
exoplatform/exo-community
(You might still hit the same permission issues.)
In your Dockerfile approach, the base image runs as an alternate USER but a COPY instruction by default makes files owned by root. As of relatively recent Docker (18.03; if you're using Docker 1.13 on CentOS/RHEL 7 this won't work) you should be able to
COPY --chown=exo server.xml /opt/exo/conf
Or if that won't work, you can explicitly switch to the root user and back
COPY server.xml /opt/exo/conf
USER root
RUN chown exo /opt/exo/conf/server.xml
USER exo

Docker : directory mapped in volume is not created with same user of host

i'm running a docker container inside my server .
in my server (host) i ve this folder : /opt/myapp/myFolder
where myFolder has 755 permissions and myuser:mygroup ownership
I'm using docker-compose to run my container , thus i'm mounting that same volume
mycontainer:
...
volumes:
- /opt/myapp/myFolder:/opt/myapp/myFolder
...
The probleme that , inside my container , my directory "myFolder" still having the same host permissions (755) but not the same ownership
and the ownership looks like this 65534:65534
this results on permission denied in some other treatment inside this folder.
normally inside the container "myFolder" still keeping the same host ownership .
Note : tthe user myuser and the group mygroup do exist inside the container.
Suggestions ?
Docker doesn't create users and groups to match the mounted folder's ownership.
You can add the user inside your container to the folder's group, using the group id (GID).
Check out "Docker and file system permissions" article.

Data permissions Docker for Windows

I'm using Docker for Windows, with owncloud container, and I shared volumes, setting up on docker-compose.yml, in order to persist the data.
Extract from my docker-compose.yml
` owncloud:
image: jobel/owncloud:1.1
links:
- db:db
ports:
- 8002:80
volumes:
- f:/Program Files/Docker/Docker VM/owncloudconfig:/var/www/html
- f:/Program Files/Docker/Docker VM/owncloudconfig/apps:/var/www/html/apps
- f:/Program Files/Docker/Docker VM/owncloudconfig/config:/var/www/html/config
- f:/Program Files/Docker/Docker VM/owncloudconfig/data:/var/www/html/data
`
Data are present but when I try to connect on my web browser, it says : "Your data folder can be read by other users. Please change the directory permissions in 0770 mode so that the content is not listed by other users." (translate fr->eng)
But how can I change the windows folder permissions to 0770 ? ;(
Or what are the others solutions?
Thank you in advance for your answer.
In the Windows client, you can configure the docker to allow read/write on specific drives. In your case, it is the F: drive. This should fix your permissions problem.
The web-server running in Docker is checking the folder permissions, which is nothing to do with windows; you need to verify the folder permissions inside Docker itself
Below is an example which you can play with, you just need to let docker execute the Linux command in a container
hope this helps
eg:
$ docker container exec -t local-container ls -ld /var/www/html/config
$ docker container exec -t local-container chmod 0770 /var/www/html/config

Resources