https://github.com/creemama/docker-run-non-root
Run Docker containers with a non-root user by default
https://github.com/creemama/docker-run-non-root
docker linux non-root root shell shell-scripts
Last synced: 3 months ago
JSON representation
Run Docker containers with a non-root user by default
- Host: GitHub
- URL: https://github.com/creemama/docker-run-non-root
- Owner: creemama
- License: mit
- Created: 2018-08-18T16:55:27.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2019-03-17T17:15:20.000Z (over 7 years ago)
- Last Synced: 2025-04-16T00:42:03.473Z (about 1 year ago)
- Topics: docker, linux, non-root, root, shell, shell-scripts
- Language: Dockerfile
- Homepage: https://github.com/creemama/run-non-root
- Size: 33.2 KB
- Stars: 11
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# run-non-root
> Run Docker containers with a non-root user by default.
[](https://travis-ci.org/creemama/run-non-root) [](https://github.com/creemama/docker-run-non-root) [](https://hub.docker.com/r/creemama/run-non-root/)
`run-non-root` runs Linux commands as a non-root user, creating a non-root user if necessary.
This allows us to
**run Docker containers with a non-root user by default**
without having to specify a `USER` with hardcoded UIDs and GIDs in our Dockerfiles.
# Supported tags and respective `Dockerfile` links
* [`1.5.1-alpine`, `1.5-alpine`, `1-alpine`, `1.5.1`, `1.5`, `1`, `latest` *(alpine/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/alpine/Dockerfile)
* [`1.5.1-centos`, `1.5-centos`, `1-centos`, `centos` *(centos/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/centos/Dockerfile)
* [`1.5.1-debian`, `1.5-debian`, `1-debian`, `debian` *(debian/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/debian/Dockerfile)
* [`1.5.1-fedora`, `1.5-fedora`, `1-fedora`, `fedora` *(fedora/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/fedora/Dockerfile)
* [`1.5.1-ubuntu`, `1.5-ubuntu`, `1-ubuntu`, `ubuntu` *(ubuntu/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/ubuntu/Dockerfile)
**Examples**
* [`1.5.1-certbot` *(certbot/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/certbot/Dockerfile)
* [`1.5.1-certbot-renew-cron` *(certbot-renew-cron/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/1.5.1/certbot-renew-cron/Dockerfile)
* [`1.5.1-node-10.15.3` *(node/Dockerfile)*](https://github.com/creemama/docker-run-non-root/blob/cc2a7a3e804b2ac88e8dd9240e1b9ece7f79e13b/node/Dockerfile)
# run-non-root
[run-non-root](https://github.com/creemama/run-non-root) is a shell script that runs Linux commands as a non-root user.
```
Usage:
run-non-root [options] [--] [COMMAND] [ARGS...]
Run Linux commands as a non-root user, creating a non-root user if necessary.
Options:
-c, --chown Colon-separated list of files and directories to run
"chown USERNAME:GID" on before executing the
command; you can use this option multiple times
instead of using a colon-separated list; run-non-root
ignores this option if you are already running as a
non-root user; unlike -p this option is non-recursive.
-d, --debug Output debug information; using --quiet does not
silence debug output. Double up (-dd) for more output.
-f, --group GROUP_NAME The group name to use when executing the command; the
default group name is USERNAME or nonroot; this
option is ignored if we are already running as a
non-root user or if the GID already exists; this
option overrides the RUN_NON_ROOT_GROUP environment
variable.
-g, --gid GID The group ID to use when executing the command; the
default GID is UID or a new ID determined by
groupadd; this option is ignored if we are already
running as a non-root user; this option overrides the
RUN_NON_ROOT_GID environment variable.
-h, --help Output this help message and exit.
-i, --init Run an init (the tini command) that forwards signals
and reaps processes; this matches the docker run
option --init.
-p, --path Colon-separated list of directories to run
"chown -R USERNAME:GID" on before executing the
command; you can use this option multiple times
instead of using a colon-separated list; if a
directory does not exist, run-non-root attempts to
create it; run-non-root ignores this option if you
are already running as a non-root user; unlike -c
this option is recursive.
-q, --quiet Do not output "Running ( COMMAND ) as USER_INFO ..."
or warnings; this option does not silence --debug
output.
-t, --user USERNAME The username to use when executing the command; the
default is nonroot; this option is ignored if we are
already running as a non-root user or if the UID
already exists; this option overrides the
RUN_NON_ROOT_USER environment variable.
-u, --uid UID The user ID to use when executing the command; the
default UID is GID or a new ID determined by
useraddd; this option is ignored if we are already
running as a non-root user; this option overrides the
RUN_NON_ROOT_UID environment variable.
-v, --version Ouput the version number of run-non-root.
Environment Variables:
RUN_NON_ROOT_COMMAND The command to execute if a command is not given; the
default is bash; if bash does not exist, the default
is sh.
RUN_NON_ROOT_GID The group ID to use when executing the command; see
the --gid option for more info.
RUN_NON_ROOT_GROUP The group name to use when executing the command; see
the --group option for more info.
RUN_NON_ROOT_UID The user ID to use when executing the command; see
the --uid option for more info.
RUN_NON_ROOT_USER The username to use when executing the command; see
the --user option for more info.
Examples:
# Run bash or sh as a non-root user.
run-non-root
# Run id as a non-root user.
run-non-root -- id
# Run id as a non-root user using options and the given user specification.
run-non-root -f ec2-user -g 1000 -t ec2-user -u 1000 -- id
# Run id as a non-root user using environment variables
# and the given user specification.
export RUN_NON_ROOT_GID=1000
export RUN_NON_ROOT_GROUP=ec2-user
export RUN_NON_ROOT_UID=1000
export RUN_NON_ROOT_USER=ec2-user
run-non-root -- id
```
# Examples
```sh
# Run sh as a non-root user.
docker run -it --rm creemama/run-non-root:latest
# Output: Running ( su-exec nonroot:1000 sh ) as uid=1000(nonroot) gid=1000(nonroot) groups=1000(nonroot) ...
# Run id as a non-root user.
docker run -it --rm creemama/run-non-root:latest --q -- id
# Output: uid=1000(nonroot) gid=1000(nonroot) groups=1000(nonroot)
# Run id as a non-root user using options and the given user specification.
docker run -it --rm creemama/run-non-root:latest \
-f ec2-user -g 1000 -q -t ec2-user -u 1000 -- id
# Output: uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user)
# Run id as a non-root user using environment variables
# and the given user specification.
docker run \
-e RUN_NON_ROOT_GID=1000 \
-e RUN_NON_ROOT_GROUP=ec2-user \
-e RUN_NON_ROOT_UID=1000 \
-e RUN_NON_ROOT_USER=ec2-user \
-it --rm creemama/run-non-root:latest \
-q -- id
# Output: uid=1000(ec2-user) gid=1000(ec2-user) groups=1000(ec2-user)
# Run as yourself.
docker run -it --rm creemama/run-non-root:latest \
-f $(id -gn) -g $(id -g) -t $(id -nu) -u $(id -u) \
-- id
# Run as root if you need to.
docker run -it --rm creemama/run-non-root:latest -qu 0 -- whoami
# Output: root
```
# Docker and `run-non-root`
As we all know, [processes in containers should not run as root](https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b).
There are several approaches to run as a non-root user.
**Specify a `USER` in your Dockerfile**
One approach is to create a user via `useradd` and specify a [`USER`](https://docs.docker.com/engine/reference/builder/#user) in your Dockerfile.
```
FROM debian:stretch
RUN groupadd -g 999 appuser && \
useradd -r -u 999 -g appuser appuser
USER appuser
CMD ["cat", "/tmp/secrets.txt"]
```
The upside to this approach is that the container, by default, runs as `appuser` instead of root.
The downside is that `appuser` has a specific UID and GID that [you cannot change without some work](https://www.cyberciti.biz/faq/linux-change-user-group-uid-gid-for-all-owned-files/).
**Specify a UID when starting your container**
Another approach is to use the `-u` or `--user` option.
```sh
docker run -it --rm \
--user $(id -u):$(id -g) \ # Run as the given user.
--volume $(app):/app \ # Mount the source code.
--workdir /app \ # Set the working dir.
my-docker/my-build-environment:latest \ # The build image
make assets # The command
```
The upside to this approach is that you have control of the specific UID and GID of the user running the container.
The [downside](https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15) is that your user may be HOME-less and nameless. In other words,
the user might have no home directory and `whoami` might not find a name for the user.
Basically, unless the UID you specified is in the `getent passwd` list, your container does not know about the user you specified.
**Specify `run-non-root` as your `ENTRYPOINT`**
Using `run-non-root` as the `ENTRYPOINT` of your container overcomes the downsides of the aforementioned approaches.
From a base image:
```
FROM alpine:3.9
...
ADD https://raw.githubusercontent.com/creemama/run-non-root/master/run-non-root.sh /usr/local/bin/run-non-root
RUN chmod +rx /usr/local/bin/run-non-root
ENTRYPOINT ["run-non-root"]
CMD ["--", "/your/program", "-and", "-its", "arguments"]
```
From one of run-non-root's images:
```
FROM creemama/run-non-root:1.5.1-alpine
...
CMD ["--", "/your/program", "-and", "-its", "arguments"]
```
With this approach, you do not have to specify `USER` in your Dockerfile or use the `--user` option when calling `docker run`. Your container runs as a non-root user by default.
If `run-non-root` creates the non-root user (which is nonroot by default), this user will have a home directory, and `whoami` will return that user's name.
# `tini`
Use `run-non-root` in conjunction with [`tini`](https://github.com/krallin/tini) to handle zombie reaping and signal forwarding by using the `--init` option.
```sh
$ docker run -it --rm creemama/run-non-root:latest --init -q -- ps aux
PID USER TIME COMMAND
1 nonroot 0:00 tini -- ps aux
17 nonroot 0:00 ps aux
```