Docker: mounting/sharing a single sock file? - linux

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.

Related

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

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

How do I add the local users to my docker container?

I want to know how I can add the local users of my server to a docker container. I don't need to import their files, I just need a username/password/privileges with new home directory in the docker container for every user in my system. For example, suppose my docker container contains the following users:
Host System:
admin: who has root access and rw access to all
bob: a regular non-sudo user
joe: another regular non-sudo user
Then the Docker Container must have users:
admin: who has root access and rw access to all
bob: a regular non-sudo user
joe: another regular non-sudo user
The Docker container and the system are both running linux, though the system is red hat and the container is ubuntu.
EDIT: I don't want to mount /etc/ files if possible, as this can create a two way security vulnerability as pointed out by #caveman
You would have to mount all relevant linux files using -v like /etc/passwd, /etc/shadow, /ect/group, and /etc/sudoers. Though I can't recommend this due to the security risks, if anyone gets root access in the container they can add users on the host or change passwords since he mount works both ways.
The list of files is not exhaustive, for example, you have to also make sure the shell exacutables exist within the container. When testing this I had to make a symbolic link from /usr/bin/zsh to /bin/bash for example since my user has the zsh shell configured which was not present in the docker image.
If you want to use these users to interact with mounted files, you also have to make sure that user namespace remapping is disabled, or specify that you want to use the same user namespace as the host with the --userns=host flag. Again, not recommended since it is a security feature, so use with care.
Note: Once you have done all this you can use su - {username} to switch to all your existing users. The -u options doesn't work since docker checks the /etc/passwd file before mounting and will give an error.

docker uid/gid mapping changes on different host

I have a docker container build on one system where uid = 1000 and gid = 300
When I then try to use that same container on the jenkins server these uid/gid are taken by different user and groups so when I try to execute commands in the container it fails due to permissions.
How can I run the container with the users mapped to the correct uid/gid
There are a few options to handle uid/gid mismatches with host volumes.
open permissions up on the host directory, often considered bad by the security team, for good reason, but also really easy to do.
build a new image for each host where it may run with different uid/gid
switch to named volumes instead. If you don't need direct access to the volume contents from the host, this is recommended.
fix permission problems with an entrypoint.
I go into more detail on some of these in my DockerCon talk here.
There's also another example of the entrypoint solution where I configured a Jenkins container to fix the docker gid to match the mounted docker socket: https://github.com/sudo-bmitch/jenkins-docker

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

Shared volume/file permissions/ownership (Docker)

I'm having a slightly annoying issue while using a Docker container (I'm on Ubuntu, so no virtualization like VMWare or b2d). I've built my image, and have a running container that has one shared (mounted) directory from my host, and one shared (mounted) file from my host. Here's the docker run command in full:
docker run -dit \
-p 80:80 \
--name my-container \
-v $(pwd)/components:/var/www/components \
-v $(pwd)/index.php:/var/www/index.php \
my-image
This works great, and both /components (and its contents) and the file are shared appropriately. However, when I want to make changes to either the directory (e.g. adding a new file or folder), or edit the mounted file (or any file in the directory), I'm unable to do so due to incorrect permissions. Running ls- lFh shows that the owner and group for the mounted items have been changed to libuuid:libuuid. Modifying either the file or parent directory requires root permissions, which impedes my workflow (as I'm working from Sublime Text, not Terminal, I'm presented with a popup for admin privs).
Why does this occur? How can I work around this / handle this properly? From Managing Data Volumes: Mount a Host File as a Data Volume:
Note: Many tools used to edit files including vi and sed --in-place may result in an inode change. Since Docker v1.1.0, this will produce an error such as “sed: cannot rename ./sedKdJ9Dy: Device or resource busy”. In the case where you want to edit the mounted file, it is often easiest to instead mount the parent directory.
This would seem to suggest that instead of mounting /components and /index.php, I should instead mount the parent directory of both. Sounds great in theory, but based on the behavior of the -v option and how it interacts with /directory, it would seem that every file in my parent directory would be altered to be owned by libuuid:libuuid. Additionally, I have lots of things inside the parent directory that are not needed in the container - things like build tools, various files, some compressed folders, etc. Mounting the whole parent directory would seem to be wasteful.
Running chown user:group on /components and /index.php on my host machine allow me to work around this and seem to continue to sync with the container. Is this something I'll need to do every time I run a container with mounted host volumes? I'm guessing that there is a more efficient way to do this, and I'm just not finding an explanation for my particular use-case anywhere.
I am using this container for development of a module for another program, and have no desire to manage a data-only container - the only files that matter are from my host; persistence isn't needed elsewhere (like a database, etc).
Dockerfile
/setup
Created on pastebin to avoid an even longer post. Never expires.
After creating the image, this is the run command I'm using:
docker run -dit \
-p 80:80 \
--name my-container \
-v $(pwd)/components:/var/www/wp-content/plugins/my-plugin-directory/components \
-v $(pwd)/index.php:/var/www/wp-content/plugins/my-plugin-directory/index.php \
my-image
It looks like your chown -R nginx:nginx ... commands inside your container are changing the ownership bits on your files to be owned by libuuid on your host machine.
See Understanding user file ownership in docker: how to avoid changing permissions of linked volumes for a basic explanation on how file ownership bits work between your host and your docker containers.

Resources