Solving Docker Container Permissions Problems

      Comments Off on Solving Docker Container Permissions Problems

One of the most surprising problems you run into using Docker is how daunting it can be to get containers to work seamlessly with attached data storage such as local volumes (-v) or data containers (--volumes-from).

Looking for Solutions

None of the proposed solutions are really good.  The best is to use data-containers and burn hardcoded permissions directly into the images.   But, in real-world scenarios, there really are no good solutions that work and people are still struggling to find good answers.  Some people even cite these problems among their primary reasons for giving up on using Docker completely.

Well, I think we’ve found a better way, and we use it now in all our images.  It requires that you do the following:

  1. Design your container so that the contained application does not care what user credentials it uses.   This is a walloping good idea by the way, and this alone makes your container more flexible and easy to manage.
  2. Configure your container start-up to create a new user which matches the credentials of the shared volume, then run all services under that user.

This is surprisingly easy, and I’ll show you how it can be done using the vanilla Ubuntu image.  You can try this in any directory you wish, so long as you’re at the shell prompt.

Here’s How

First, create an executable start-up script that handles item #2 above.  For example, for Ubuntu, I created start.sh in a test directory and put this in it:

#!/bin/sh

# Create a new user, appsuser, match the UID to /data
useradd -u `ls -ld /data | awk '{print $3}'` -p none appsuser

# Fire up the app under the newly created user
exec su - appsuser -c /your/application

Now, run docker in the same directory like this:

docker run -i -t --rm -v $PWD:/data ubuntu /data/start.sh

Now, /your/application is running inside the container with full permissions to the attached volume, whatever they are.  (Replace /your/application with /bin/sh to try it quickly and interactively.

That’s it!

We’ve found this to be an excellent pattern, and has resulted in having containers which can use attached storage on any host, or any data container, without having any permission problems whatsoever.

Refining the Solution

The above solution, while workable and simple, usually needs to be refined for production images.  The biggest problem is that it leaves a PID 1 process running which is superfluous and gets in the way.

One of the reasons we wrote the Chaperone process manager was to solve this exact problem.   Chaperone’s –create-user option is designed specifically to allow you to create a new user, and even have it match file system permissions, just as described above.  Even if your container doesn’t need a process manager, it’s better having Chaperone sitting at PID#1 than some dormant shell script.

For a good example of how this simplifies container deployment, take a look at the “Configuring Attached Storage” instructions which I included on my docker-keybox image.  Simple, easy, and accommodates any persistent storage strategy.

If you like this pattern, whether you use our solutions or build your own, please let us know how it goes.  I’m always interested in new approaches to refining the Docker experience.

Comments

comments