I already run my docker build
and docker run
without sudo. However, when I launch a process inside a docker container, it appears as a root process on top
on the host (not inside the container).
While it cannot access the host filesystem because of namespacing and cgroups from docker, is it still more dangerous than running as a simple user?
If so, how is the right way of running things inside docker as non root?
Should I just do USER nonroot
at the end of the Dockerfile?
UPDATE:
root it also needed for building some things. Should I put USER
on the very top of the Dockerfile and then install sudo
together with other dependencies, and then use sudo
only when needed in the build?
Can someone give a simple Dockerfile example with USER in the beggining and installing and using sudo
?
Running the container as root
brings a lot of risks. Although being root
inside the container is not the same as root
on the host machine (some more details here) and you're able to deny a lot of capabilities during container startup, it is still the recommended approach to avoid being root
.
Usually it is a good idea to use the USER
directive in your Dockerfile after you install some general packages/libraries. In other words - after the operations that require root
privileges. Installing sudo
in a production service image is a mistake, unless you have a really good reason for it. In most cases - you don't need it and it is more of a security issue. If you need permissions to access some particular files or directories in the image, then make sure that the user you specified in the Dockerfile can really access them (setting proper uid
, gid
and other options, depending on where you deploy your container). Usually you don't need to create the user beforehand, but if you need something custom, you can always do that.
Here's an example Dockerfile for a Java application that runs under user my-service
:
FROM alpine:latest
RUN apk add openjdk8-jre
COPY ./some.jar /app/
ENV SERVICE_NAME="my-service"
RUN addgroup --gid 1001 -S $SERVICE_NAME && \
adduser -G $SERVICE_NAME --shell /bin/false --disabled-password -H --uid 1001 $SERVICE_NAME && \
mkdir -p /var/log/$SERVICE_NAME && \
chown $SERVICE_NAME:$SERVICE_NAME /var/log/$SERVICE_NAME
EXPOSE 8080
USER $SERVICE_NAME
CMD ["java", "-jar", "/app/some.jar"]
As you can see, I create the user beforehand and set its gid
, disable its shell and password login, as it is going to be a 'service' user. The user also becomes owner of /var/log/$SERVICE_NAME
, assuming it will write to some files there. Now we have a lot smaller attack surface.