Well I'm running a container which will create/modify some files that I need to persist outside the life-cycle of the container. As a result, I am voluming a folder into the container for that purpose:
docker run -v $(pwd)/data:/app/data my-image
On the first run,
$(pwd)/data does not exist, so Docker will create it for me. However, it creates it as the user its own daemon process is being executed as, which is
root. This is problematic since the user within the container obviously is not
To fix this permission issue, I have created a user group in the host machine with the same ID as the user within the container, and have given them access to the parent folder of
$(pwd)/data, and added group permission settings on the folder (
chmod g+s). So if I run the following command as root:
sudo mkdir whatver
whatever will be modifiable by that group and by extension, by the container's user. however when Docker creates the folder
$(pwd)/data, it still is created as belonging to the group
root, and again the user within the container cannot modify data inside it.
Right now, I have worked around this by making the required folders before running the container. However this is a dirty work-around, and I am looking for a cleaner solution. Has anyone else faced this issue? Is it an issue with Docker not respecting the group permission settings on the parent folder or am I missing something here / doing something wrong?
I don't consider making the folders first a dirty workaround, that's a best practice to me. Docker is running a bind mount for you, and this will fail when the source directory does not exist. For user convenience, docker will create this directory for you when you make a host mount and the directory is missing, but there's no need to use this functionality and you'll find other types of mounts will not perform the directory creation for you (e.g. the
--mount syntax often used by swarm mode).
You can start your container as root and fix the permissions on the directory with an entrypoint, before running something like an
exec gosu app_user app_server at the end to drop from root to the user. I do this in the entrypoint in my docker-base images, which is useful for a developer workflow where developers often need to dynamically update the container to work with their host environment.
Otherwise, you can switch to named volumes. These will be initialized when they are new or empty using the directory contents and permissions from the image. They are a best practice when you need persistence but not direct filesystem access to the contents of the volume from users on the host. You would instead access the named volume from inside of containers that mount the volume.