Search code examples
dockergo-cddocker-in-docker

How do i give a non root user access to docker when using docker-dind?


I'm trying to run a Go CD agent using docker-dind to auto build some of my docker images.

I'm having trouble getting the user go to have access to the docker daemon.

When I try and access docker info I get the following:

[go] Task: /bin/sh ./builder.shtook: 2.820s
[START]
[USER]  go
[TAG]  manual

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.32/containers/fish/angular-cli/json: dial unix /var/run/docker.sock: connect: permission denied
Sending build context to Docker daemon  3.072kB

Step 1/8 : FROM node:8-alpine
 ---> 4db2697ce114
Step 2/8 : MAINTAINER [email protected]
 ---> Using cache
 ---> 22f46bf6b4c1
Step 3/8 : VOLUME /usr/local/share/.cache/yarn/v1
 ---> Using cache
 ---> 86b979e7a2b4
Step 4/8 : RUN apk add --no-cache --update build-base python
 ---> Using cache
 ---> 4a08b0a1fc9d
Step 5/8 : RUN yarn global add @angular/[email protected]
 ---> Using cache
 ---> 6fe4530181a5
Step 6/8 : EXPOSE 4200
 ---> Using cache
 ---> 480edc47696e
Step 7/8 : COPY ./docker-entrypoint.sh /
 ---> Using cache
 ---> 329f9eaa5c76
Step 8/8 : ENTRYPOINT /docker-entrypoint.sh
 ---> Using cache
 ---> cb1180ff8e9f
Successfully built cb1180ff8e9f
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.32/containers/fish/angular-cli/json: dial unix /var/run/docker.sock: connect: permission denied

My root user can accesss docker info properly, but the go user fails.

$ cat /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
....
adm:x:4:root,adm,daemon
wheel:x:10:root
xfs:x:33:xfs
ping:x:999:
nogroup:x:65533:
nobody:x:65534:
dockremap:x:101:dockremap,go
go:x:1000:go

My docker.sock permissions are as follows:

$ ls -alh /var/run/docker.sock
srw-rw----    1 root     993            0 Apr 20  2017 /var/run/docker.sock

What do I need to append to my Dockerfile in order to allow the go user to access the docker daemon?


Solution

  • When running a dind container, IE docker in docker, it its common place to volume mount /var/run/docker.sock:/var/run/docker.sock from the host into the dind-container.

    When this occurs, the PID is not only owned by root, but by a numeric group id from the host.

    Running the following inside the container should show you the host GID:

    $ ls -alh /var/run/docker.sock
    srw-rw----    1 root     993            0 Apr 20  2017 /var/run/docker.sock
    

    The above process is owned by group 993, 993 is derived from the host machines /etc/group -> docker role.

    As it is nearly impossible to ensure that we have a common group id when the image is first built, the group id should be assigned at runtime using your docker-entrypoint.sh file.

    My personal goal is to get this runtime user of 'go' for a GO CD go-agent, but one could substitute this approach for jenkins or any other runtime user.

    As the dind & go-agent are both based off alpine linux, the following will work for alpine-linux:

    #setup docker group based on hosts mount gid
    echo "Adding hosts GID to docker system group"
    # this only works if the docker group does not already exist
    DOCKER_SOCKET=/var/run/docker.sock
    DOCKER_GROUP=docker
    BUILD_USER=go
    
    if [ -S ${DOCKER_SOCKET} ]; then
        DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
    
        #addgroup is distribution specific
    
        addgroup -S -g ${DOCKER_GID} ${DOCKER_GROUP}
        addgroup  ${BUILD_USER} ${DOCKER_GROUP}
    fi
    

    If you exec into the container, and cat your /etc/group file, you should see the following:

    docker:x:993:go