Use Docker Compose Named Volumes as Non Root within your containers
While writing another code for a build system, I noticed something peculiar.
Defaults to Root
By default, all Docker Compose named volumes are root.
And there is not much we can do about it.
An issue for the same has been around since 2016 on GitHub
The Issue
Running the following Compose File with
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose up list
I found that cache has root access instead of 1000:1000 that I have set for my own user.
This means that the following Compose file fails. Because build tries to create hello.txt in cache.
USER_ID=$(id -u) GROUP_ID=$(id -g) docker-compose up build
Which is pretty obvious because my user does not have permission to write to that specific directory given I am 1000:1000 and not root:root.
A Hacky Workaround
We know in Docker Compose using depends_on and service_completed_successfully, make a single Docker Compose service depend on and wait for another to complete.
What if this service decided to access our volume as root (well yeah), change ownership to our user and then just finish.
This way we would have full access now that ownership has changed.
Let us view the compose file for this
It now works
You too can use that to integrate the fix within your system.
The way this works is that build service runs change-vol-ownership. change-vol-ownership performs the fixes required. Once change-vol-ownership has finished, we run build.
This all happens automatically.
Alternatives
The alternative is to manually edit the Dockerfile, run chown on all paths we are interested in.
This approach has a few flaws however:-
- Does not scale
- Needs a rebuild at our end every time upstream has changes
- Need to specify all volumes within the Dockerfile
Thus will not generalise very well
Especially because Compose allows us to have as many Dockerfiles as we want.
Credits
The credits for this belong to Michael McQuade. He mentioned a work around on the same GitHub issue