Docker images run with root privileges by default.
root user in the container is the same root (
uid:0) as on the host machine. If a user manages to break out of an application running as
root in a container, they may be able to gain access to the host machine with the same
Running containers using non-root user provides an additional layer of security against processes escaping the container due to a container engine vulnerability and thereby achieving escalated permissions on the host node.
Starting from GoCD release
v19.6.0, GoCD containers run as non-root user, by default. The Dockerized GoCD application will run as
gid:0) user instead of running as
What are the changes made to GoCD Docker Images to support running containers as non-root?
1. Add USER instruction in the Dockerfile:
The USER instruction sets the user name (or UID) to use when running the container and for any instructions that follow it in the Dockerfile.
GoCD Dockerfile adds a USER instruction to change the current user from the
root user to
uid:1000) user. This instruction will make sure that the
uid:1000) user is used while running the docker container and also for any
ENTRYPOINT instructions that follow it in the Dockerfile.
2. Add go user to root group:
OpenShift Container Platform (OCP) manages containers life-cycle with security in mind at every stage and every layer of application deployments.
By default, OpenShift prevents root user containers by running containers using an arbitrarily assigned user ID. This arbitrary user ID in the container is always a member of
root group on OCP. For an image to support running as an arbitrary user, directories and files that may be written to by processes in the image should be owned by the root group and be read/writable by that group.
Hence, to allow GoCD application to be deployed on OCP, dockerized GoCD applications run with
Note : The root group does not have any special permissions (unlike the
root user). So, there are no security concerns with this arrangement.
For more information, checkout OCP General Container Image Guidelines.
3. Modify GoCD Directories and File permissions:
The GoCD server stores all configuration, pipeline history database, artifacts, plugins, addons and logs into
/godata, whereas, additional information such as secure credentials, ssh keys can additionally be stored at
As the existing container user has changed from
go:root, the file permissions of the above mentioned directories and files are changed to
What are the Breaking Changes in GoCD Docker Image?
1. Creating directories in file-system root:
FROM gocd/gocd-server:v19.5.0 RUN mkdir /.ssh
Moving files or directories into or out of system directories (i.e., directories that are critical to the functioning of the operating system), copying files into system directories requires root privileges. As GoCD containers do not run as root,
RUN mkdir /.ssh command would result in
mkdir: /.ssh: Permission denied error.
In general, root privileges should not be needed by applications running inside the container. In GoCD's context, application-related files and directories should be created under
FROM gocd/gocd-server:v19.6.0 RUN mkdir /home/go/.ssh
Alternatively, if an application requires creating root directories, it can be achieved by switching users in the Dockerfile and executing the root directory creation instruction.
2. Installing packages:
FROM gocd/gocd-server:v19.5.0 RUN apk --update add jq
Root privileges are usually required for installing software because of the need to write to system directories. Packages can be installed by switching users in the Dockerfile.
3. go group migration:
FROM gocd/gocd-server:v19.5.0 RUN mkdir /home/go/creds RUN chown go:go /home/go/creds
go user belongs to
root group instead of
go group, the above Dockerfile can be changed to:
FROM gocd/gocd-server:v19.6.0 RUN mkdir /home/go/creds RUN chown go:root /home/go/creds
Note: Ownership of any files/directories owned by
go group needs to be changed to
root group as there will no longer be a
go group on GoCD images.
4. Custom Entrypoint Scripts:
GoCD allows running custom entrypoint scripts to configure GoCD Server before starting. These entrypoint scripts could involve instructions for installing required plugins, configuring basic authentication, etc.
Starting from GoCD release
v19.6.0, custom entrypoint scripts will run as
go user (instead of
root user). We recommend users to not include scripts requiring root privileges as part of custom entrypoint scripts.
Any pre-configuration instructions requiring root privileges should be included in a Dockerfile.
5. Shared Volume Permissions:
GoCD stores all configuration, pipeline history database, artifacts, plugins, and logs into
/godata. Whereas, secure credentials like SSH private keys among other things, can be mounted at
For GoCD to persist these configurations across container restarts,
/home/go directories can be volume mounted inside the container.
Prior to GoCD
v19.6.0, GoCD containers are run as
root user, because of which, the container user has permissions to the volume mounted folders/files. Starting from GoCD release
v19.6.0, the GoCD container user will be running as
uid:1000) user. As a result, the container non-root user will not have permissions to the volume mounted folder/files (by default).
In the Docker context, container's users are mapped with host's users. Similarly, the permissions for host mounted volumes comes from the host OS. To allow
uid:1000) within the container to have permissions to the mounted volume folders/files requires changing the mounted volume ownership to
Multiple USER instructions
The USER instruction in the Dockerfile changes the user to the specified user for the subsequent instructions in the Dockerfile. Multiple USER instructions can be used to switch the user context from root to non-root user.
FROM gocd/gocd-server:v19.6.0 USER root RUN mkdir /creds RUN chown -r go:root /creds RUN apk --update add jq USER go
In the above example, the following instruction block is executed as
root user because of the preceding
USER root instruction. And finally, the user is switched back to
USER go instruction.
RUN mkdir /creds RUN chown -r go:root /creds RUN apk --update add jq
USER go instruction after the instruction requiring root privileges is required to change the user back to
go. Failing to add
USER go instruction at the end would make container to execute as
How to verify the container user?
To verify whether the user running inside the container is root or non-root, we can execute following command(s):
1. Verify the UID of container user is non-zero:
$ docker container run gocd/gocd-server:v19.6.0 id > uid=1000(go) gid=0(root) groups=0(root)
2. Verify the container user does have access to root directory:
$ docker container run gocd/gocd-server:v19.6.0 ls /root/ > ls: can't open '/root/': Permission denied
But, what if I want to run containers as root?
Sometimes, the application container requires access to the privileged resources in order to perform its required function(s). It can be achieved by granting certain privileges to the user, or running the application container as root user.
1. Using USER root instruction:
FROM gocd/gocd-server:v19.6.0 USER root
USER root instruction can be added to the extending image to change the user context from
go user to
2. Using --user argument:
docker container run --user root:root gocd/gocd-server:v19.6.0
The container user can be specified using
--user option to the
docker container run command while starting the container from command line.
Note: Well designed systems adhere to the principle of least privilege. This simply states that an application should only have access to the resources it needs in order to perform its required function.
GoCD containerized processes are application services and therefore don’t require root access. We strongly recommend users to grant required privileges to the
go user and avoid running as