One common misconception is that containers provide a secure and isolated environment and therefore it’s fine for processes to run as root (this is the default). I mean, it’s not like it can affect the host system right? Turns out it can and it’s called “container breakout”!
With containers, you should also apply the principle of least privilege and run processes as a non-root users. This significantly reduces the attack surface because any vulnerability in the container runtime that happens to expose host resources to the container will be less likely to be taken advantage of by a container process that does not have root permissions.
Here’s a rough skeleton of how you can do this by using the
USER directive in the Dockerfile:
# Create a non-root user named "appuser" with UID 1001 RUN adduser --disabled-password --uid 1001 content # Set the working directory WORKDIR /app # Grant ownership and permissions to the non-root user for the working directory RUN chown -R appuser /app # Switch to the non-root user before CMD instruction USER appuser # ... install app dependencies ... # this may involve copying over files and compiling # Execute script CMD ["./run"]Code language: PHP (php)
One thing worth mentioning in this example is permissions.
We use the
USER instruction early on right after we change the ownership of the working directory. Since this is happening before we enter the application building phases, it’s possible that the permissions of the user
appuser is insufficient for subsequent commands. For example, maybe at some point in your docker file you need to change the permission of a file that
appuser doesn’t own or maybe it needs to write to a bind-mounted directory owned by a host user. If this applies to your situation, you can either adjust permissions as needed prior to running
USER or move
USER farther down towards the
Generally speaking, it’s also good practice to ensure that the files that are copied over from the host have their ownership changed to
appuser. This isn’t as critical as ensuring that the process itself is running as non-root via
USER since if an attacker gains privileged access, they can access any file in the container regardless of ownership. Nonetheless it’s a good practice that follows the principle of least privilege in that it scopes the ownership of the files to the users and groups that actually need it.
Other resources if you’re interested in learning more about this topic: