Docker is one of those development projects that lived up to the hype. It allows you to package and ship your application, without having to worry as much about the deployment environment.
Key phrase: “as much”
Unfortunately, it is no silver bullet. Take for instance the Jenkins’ docker repository. When you decided to use this to deploy your Jenkins instance, you probably executed:
docker run --name myjenkins -p 8080:8080 -p 50000:50000 -v /home/jenkins:/var/jenkins_home jenkins
And somewhere along the execution, you get something like this:
/usr/local/bin/jenkins.sh: line 25: /var/jenkins_home/copy_reference_file.log: Permission denied
Problem
Base on my experience, there are two culprits that cause this error. First is you mounted an inexistent volume. Second is a mismatch of uid and/or gid in the local machine and in the container.
Non-existent Volume
Consider the Jenkins above for instance. If you managed to execute bash inside your Jenkins container before it quits (there are ways to ensure your container does not exit despite encountering error which I won’t cover in this post) and run ls /var/jenkins_home
you might get:
ls: cannot access 'asdf': No such file or directory
You need to fix your volume field, ensure that /home/jenkins exist on your local machine.
But I doubt this is the case for you. Sure clumsy your fingers might be, there is a conspiracy spawned by DevOps folks to stop developers like you and me to easily spin our own Continuous Integration instance. Or like me, you have never cared about how Linux handles read/write permissions.
Mismatch Of uid/gid
Executing a simple ls -l
you get something like:
total 16 drwxrwxr-x 2 jandres jandres 4096 Jul 16 02:29 blog drwxrwxr-x 3 jandres jandres 4096 Jul 16 02:04 ci drwxrwxr-x 3 jandres jandres 4096 May 18 17:30 osx-sierra-box drwxrwxr-x 4 jandres jandres 4096 May 18 18:03 vagrant-box-osx
What interest us here is the highlighted jandres jandres. It means the file is owned by user jandres and group jandres.
When Linux creates a user foo, it will automatically create and add a user to a group with the same name foo. In the case of the Jenkins docker repo, this would be user and group jenkins.
Now you might say,
but /home/jenkins is also owned by user=jenkins and group=jenkins
Now I introduce you to uid and gid. Linux doesn’t really see user=jandres and group=jandres when it sees the file above, but rather it sees uid=1000 and gid=1000. This mapping is indicated in /etc/passwd. In my case for instance, my jenkins user have the following line in /etc/passwd:
jenkins:x:1002:1002:Continuous,Integration,,:/home/jenkins:/bin/bash
This simply means my user jenkins have a uid of 1002 (yours might differ, it doesn’t really matter). To find the guid of jenkins group, you simply do the same thing in /etc/group.
Going back to the Jenkins docker example above, despite /home/jenkins is owned by user=jenkins and group=jenkins in local machine and the same user=jenkins and group=jenkins in the container, their uid and gid might not match. For instance, in my local machine, the /etc/passwd and /etc/group indicated that uid=1002, and gid=1002, whilst this is uid=1000 and gid=1000 in the container. Hence the uid/gid mismatch!
Fix
The fix is easy enough. We just need to either use the same uid, which you can specify in a docker run
, via -u
. So in the example above, I would execute it via:
docker run -u 1002 --name myjenkins -p 8080:8080 -p 50000:50000 -v /home/jenkins:/var/jenkins_home jenkins
This tells docker container to use a user with uid 1002 to do the write operations.
That’s It! Tell me if it worked. Annoy me if it did not.
Hi! Where is docker-compose.yml code ?
Sorry, I wrote this a long time ago. Must’ve lost it since then. I removed that section to avoid misleading.
Hi
Thank you for your article. You said in the solution: “EITHER use the same uid”. I think EITHER means there’s another solution, but I can’t find this other one. Am i missing something?
Regards
No, it didn’t work. My jenkins user has the uid of 1001.
[root@192 ~]# id jenkins
uid=1001(jenkins) gid=1003(jenkins) groups=1003(jenkins),10(wheel),1001(docker),1002(sudo)
But, if I supply the -u as 1001 it is still failing. Kindly suggest.
[root@192 ~]# docker run –name jenkins –rm -u 1001 -p 8080:8080 -p 50000:50000 -v /home/jenkins:/var/jenkins_home jenkins
touch: cannot touch ‘/var/jenkins_home/copy_reference_file.log’: Permission denied
Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?