I've been playing around with Docker for a while and keep on finding the same issue when dealing with persistent data.
I create my Dockerfile
and expose a volume or use --volumes-from
to mount a host folder inside my container.
What permissions should I apply to the shared volume on the host?
I can think of two options:
So far I've given everyone read/write access, so I can write to the folder from the Docker container.
Map the users from host into the container, so I can assign more granular permissions. Not sure this is possible though and haven't found much about it. So far, all I can do is run the container as some user:
docker run -i -t -user="myuser" postgres
, but this user has a different UID than my hostmyuser
, so permissions do not work. Also, I'm unsure if mapping the users will pose some security risks.
Are there other alternatives?
How are you guys/gals dealing with this issue?
To share folder between docker host and docker container, try below command
The -v flag mounts the current working directory into the container. When the host directory of a bind-mounted volume doesn’t exist, Docker will automatically create this directory on the host for you,
However, there are 2 problems we have here:
Solution:
Container: create a user say 'testuser', by default user id will be starting from 1000,
Host: create a group say 'testgroup' with group id 1000, and chown the directory to the new group(testgroup
Base Image
Use this image: https://hub.docker.com/r/reduardo7/docker-host-user
or
Important: this destroys container portability across hosts.
1)
init.sh
2)
Dockerfile
3) run.sh
4) Build with
docker
4) Run!
Try to add a command to Dockerfile
credits goes to https://github.com/denderello/symfony-docker-example/issues/2#issuecomment-94387272
Here's an approach that still uses a data-only container but doesn't require it to be synced with the application container (in terms of having the same uid/gid).
Presumably, you want to run some app in the container as a non-root $USER without a login shell.
In the Dockerfile:
Then, in entrypoint.sh:
A very elegant solution can be seen on the official redis image and in general in all official images.
Described in step-by-step process:
As seen on Dockerfile comments:
gosu is an alternative of
su
/sudo
for easy step-down from root user. (Redis is always run withredis
user)/data
volume and set it as workdirBy configuring the /data volume with the
VOLUME /data
command we now have a separate volume that can either be docker volume or bind-mounted to a host dir.Configuring it as the workdir (
WORKDIR /data
) makes it be the default directory where commands are executed from.This means that all container executions will run through the docker-entrypoint script, and by default the command to be run is redis-server.
docker-entrypoint
is a script that does a simple function: Change ownership of current directory (/data) and step-down fromroot
toredis
user to runredis-server
. (If the executed command is not redis-server, it will run the command directly.)This has the following effect
If the /data directory is bind-mounted to the host, the docker-entrypoint will prepare the user permissions before running redis-server under
redis
user.This gives you the ease-of-mind that there is zero-setup in order to run the container under any volume configuration.
Of course if you need to share the volume between different images you need to make sure they use the same userid/groupid otherwise the latest container will hijack the user permissions from the previous one.
For secure and change root for docker container an docker host try use
--uidmap
and--private-uids
optionshttps://github.com/docker/docker/pull/4572#issuecomment-38400893
Also you may remove several capabilities (
--cap-drop
) in docker container for securityhttp://opensource.com/business/14/9/security-for-docker
UPDATE support should come in
docker > 1.7.0
UPDATE Version
1.10.0
(2016-02-04) add--userns-remap
flag https://github.com/docker/docker/blob/master/CHANGELOG.md#security-2