Add support for running Docker container as non-root user using docker-entrypoint.sh
This pull request introduces a new feature that allows running the listmonk Docker container as a non-root user by specifying the UID and GID through environment variables.
This pull-request ensures backwards compatibility and super seeds pull-request #1891
Changes
Added a new script as the Docker entrypoint to handle user and group setup docker-entrypoint.sh with the added behavior:
- If the user does not supply UID and GID, the container runs as root.
- If the user supplies UID and/or GID, the script:
- Creates the appropriate group and user if they do not already exist.
- Applies the specified UID and GID.
- Changes the ownership of the /listmonk directory to the specified user and group.
When the Docker image runs, it displays the UID, GID, USERNAME, and GROUP NAME that the Docker container is using.
docker run -e UID=1001 -e GID=1001 c1db2101ad2e
Launching listmonk with user=[app] group=[app] uid=[1001] gid=[1001]
Advantages
- Improved Security: Running containers as non-root users reduces the potential impact of security vulnerabilities. It limits the access permissions of the container, minimizing the risk of privilege escalation attacks.
- Compliance: Many security guidelines, best practices and bigger organizations don't allow running applications as the root user. This change helps in complying with such security standards.
Usage
Docker
docker run -e UID=1001 -e GID=1001 listmonk/listmonk
Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: listmonk
spec:
containers:
- name: listmonk
image: listmonk/listmonk
env:
- name: UID
value: "1001"
- name: GID
value: "1001"
securityContext:
runAsUser: 1001
runAsGroup: 1001
Implementation notes
If user doesn't supply a GID and UID the docker-entrypoint.sh assumes the root user keeping the legacy implementation working as expected.
docker run listmonk/listmonk
Launching listmonk with user=[root] group=[root] uid=[0] gid=[0]
If the user specifies UID and GID that don't exist inside the /etc/passwd/ and /etc/groups the docker-entrypoint.sh creates the proper id's in this case UID=1001 and GID=1001 and assigned the user name app and group name app as default.
docker run -e UID=1001 -e GID=1001 listmonk/listmonk
Launching listmonk with user=[app] group=[app] uid=[1001] gid=[1001]
If the user supplies UID and GID that exist inside the /etc/passwd and /etc/groups the docker-entrypoint.sh respects the choose user id and groups and doesn't create them since they already exists but assume them.
docker run -e UID=22 -e GID=65534 listmonk/listmonk
Launching listmonk with user=[sshd] group=[nobody] uid=[22] gid=[65534]
This is an ls -la of the docker container we we can see that the last step of the script is applying to the /listmonk folder the appropriate user and permissions as specified by the UID=22 and GID=65534:
docker run -ti --rm -e UID=22 -e GID=65534 listmonk/listmonk
Launching listmonk with user=[sshd] group=[nobody] uid=[22] gid=[65534]
/listmonk $ ls -la
total 17436
drwxr-xr-x 1 sshd nobody 4096 Jun 10 16:00 .
drwxr-xr-x 1 root root 4096 Jun 10 16:27 ..
-rw-r--r-- 1 sshd nobody 270 Jun 6 17:37 config-demo.toml
-rw-r--r-- 1 sshd nobody 1029 Jun 6 17:37 config.toml
-rwxr-xr-x 1 sshd nobody 17833192 Jun 10 16:00 listmonk
@mr-karan could you please help review this?
Looks good! This is backward compatible as well, since existing setups will have UID/GID as 0. Just a note on added deps:
shadowis required foradduser/groupaddsu-execto run this as a different user context.
Overall LGTM :+1: @lmmendes
I was also looking forward to having this, thanks @lmmendes.
Thanks @lmmendes. If you could resolve the merge conflict, we could merge this PR.
@knadh Will have it fixed until end of the day.
@knadh merge conflicts are fixed as requested.
I did a small change to the pull-request to make things clear, ended up renaming UID and GID to PUID and PGID, the impact to existing users is none, since this change is part of this existing feature.