Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 770
Jack Murphy Avatar asked Feb 01 '26 03:02

Jack Murphy


2 Answers

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
like image 146
Jack Murphy Avatar answered Feb 03 '26 18:02

Jack Murphy


This is a slightly modified version of @Jack's answer.

I created a docker-entrypoint.sh which will determine the GID and reuse the group if it already exists. Primarily on Docker for Windows machines the Docker socket is using root. This would need runuser as su will only work if the user's shell is not set to nologin which in my case is set to nologin

#!/bin/sh
set -e
DOCKER_SOCKET=/var/run/docker.sock
RUNUSER=jobberuser

if [ -S ${DOCKER_SOCKET} ]; then
    DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
    DOCKER_GROUP=$(getent group ${DOCKER_GID} | awk -F ":" '{ print $1 }')
    if [ $DOCKER_GROUP ]
    then
        addgroup $RUNUSER $DOCKER_GROUP
    else
        addgroup -S -g ${DOCKER_GID} docker
        addgroup $RUNUSER docker
    fi
fi
exec runuser -u $RUNUSER -- $@
like image 21
Archimedes Trajano Avatar answered Feb 03 '26 17:02

Archimedes Trajano