From 145b9c7d5d79042fadb9d2fa4752f36adeeac678 Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Wed, 16 Apr 2025 01:21:05 +0200 Subject: [PATCH 1/9] Run container image as non-root user by default. After installing additional pip packages, the container will adjust required permissions and run both django-admin and gunicorn commands as user `nemo:nemo`. UID and GID are 963 by default, but can be set using Docker Environment variables `PUID` and `GUID`, without need to recompile the image. --- Dockerfile | 3 +++ start_NEMO_in_Docker.sh | 33 +++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 46d9c427c..0d53df93a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,4 +29,7 @@ EXPOSE 8000/tcp COPY start_NEMO_in_Docker.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/start_NEMO_in_Docker.sh +# Add non-root user +RUN addgroup --system --gid 963 nemo && \ + adduser --system --home /home/nemo --shell /usr/bin/bash --gid 963 --uid 963 --comment "NEMO user" nemo CMD ["start_NEMO_in_Docker.sh"] diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index e644d4878..b4d440e4d 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -1,5 +1,4 @@ #!/bin/bash - # Exit if any of following commands fails set -e @@ -10,11 +9,37 @@ else echo "No additional Python packages to install." fi +# Set the PUID and PGID environment variables +PUID=${PUID:-963} +PGID=${PGID:-963} +# Change the user and group IDs +if [ "$PGID" -eq 0 ]; then + # If PGID is 0, use the root group + NEMO_GROUP="root" +else + NEMO_GROUP="nemo" + groupmod -g "$PGID" "$NEMO_GROUP" +fi +if [ "$PUID" -eq 0 ]; then + # If PUID is 0, use the root user + NEMO_USER="root" +else + NEMO_USER="nemo" + usermod -u "$PUID" "$NEMO_USER" +fi + +# Change the ownership of the application directory +if [ "$PUID" -ne 0 ]; then + chown -R nemo:nemo /nemo + chown -R root:nemo /etc/gunicorn_configuration.py +fi +echo "Running NEMO as user '${NEMO_USER}' (uid: ${PUID}), primary group '${NEMO_GROUP}' (gid: ${PGID})" + # Collect static files -django-admin collectstatic --no-input --clear +su "${NEMO_USER}" -g "${NEMO_GROUP}" -c "django-admin collectstatic --no-input --clear" # Run migrations to create or update the database -django-admin migrate +su ${NEMO_USER} -c "django-admin migrate" # Run NEMO -exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application +su ${NEMO_USER} -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" From 4e067838ab0a2521043d8211528d411f180ff399 Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sat, 19 Apr 2025 23:38:57 +0200 Subject: [PATCH 2/9] Simplified docker non-root startup script. --- start_NEMO_in_Docker.sh | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index b4d440e4d..471d6e450 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -12,34 +12,24 @@ fi # Set the PUID and PGID environment variables PUID=${PUID:-963} PGID=${PGID:-963} -# Change the user and group IDs -if [ "$PGID" -eq 0 ]; then - # If PGID is 0, use the root group - NEMO_GROUP="root" +# If PUID is not 0 (root) +if [ -n "$PUID" ]; then + # Change the user and group IDs + usermod -u "$PUID" -g "$PGID" nemo + # Change the ownership of the application directory + chown -R nemo:nemo /nemo + chown -R root:nemo /etc/gunicorn_configuration.py + NEMO_USER=nemo else - NEMO_GROUP="nemo" - groupmod -g "$PGID" "$NEMO_GROUP" + NEMO_USER=root fi -if [ "$PUID" -eq 0 ]; then - # If PUID is 0, use the root user - NEMO_USER="root" -else - NEMO_USER="nemo" - usermod -u "$PUID" "$NEMO_USER" -fi - -# Change the ownership of the application directory -if [ "$PUID" -ne 0 ]; then - chown -R nemo:nemo /nemo - chown -R root:nemo /etc/gunicorn_configuration.py -fi -echo "Running NEMO as user '${NEMO_USER}' (uid: ${PUID}), primary group '${NEMO_GROUP}' (gid: ${PGID})" +echo "Running NEMO as user '$(id $NEMO_USER)'" # Collect static files -su "${NEMO_USER}" -g "${NEMO_GROUP}" -c "django-admin collectstatic --no-input --clear" +su "${NEMO_USER}" -c "django-admin collectstatic --no-input --clear" # Run migrations to create or update the database -su ${NEMO_USER} -c "django-admin migrate" +su "${NEMO_USER}" -c "django-admin migrate" # Run NEMO -su ${NEMO_USER} -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" +su "${NEMO_USER}" -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" From f5a3b4f564d0b430c11cb57243e4f3b4c625289e Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sat, 19 Apr 2025 23:53:14 +0200 Subject: [PATCH 3/9] Fix group change in docker non-root startup script. --- start_NEMO_in_Docker.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index 471d6e450..3e9bc77da 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -12,6 +12,9 @@ fi # Set the PUID and PGID environment variables PUID=${PUID:-963} PGID=${PGID:-963} +if [ -n "$PGID" ]; then + groupmod -g "$PGID" nemo +fi # If PUID is not 0 (root) if [ -n "$PUID" ]; then # Change the user and group IDs From 8e729a77fb03c3a9191e01c19f52bb6ca179d67f Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sat, 19 Apr 2025 23:58:17 +0200 Subject: [PATCH 4/9] Docker non-root: only redefine primary group if not root. --- start_NEMO_in_Docker.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index 3e9bc77da..90a8ede08 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -12,11 +12,11 @@ fi # Set the PUID and PGID environment variables PUID=${PUID:-963} PGID=${PGID:-963} -if [ -n "$PGID" ]; then - groupmod -g "$PGID" nemo -fi # If PUID is not 0 (root) if [ -n "$PUID" ]; then + if [ -n "$PGID" ]; then + groupmod -g "$PGID" nemo + fi # Change the user and group IDs usermod -u "$PUID" -g "$PGID" nemo # Change the ownership of the application directory From 56b181318fca629dea14cdcd2a2cafedf6b45862 Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sun, 20 Apr 2025 00:17:09 +0200 Subject: [PATCH 5/9] Docker non-root: further simplified logic, following LinuxServer example. https://github.com/linuxserver/docker-baseimage-alpine/blob/ac17141dc88185129eebf93eb37693417030e6e2/root/etc/s6-overlay/s6-rc.d/init-adduser/run --- start_NEMO_in_Docker.sh | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index 90a8ede08..2ff7c278b 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -12,27 +12,21 @@ fi # Set the PUID and PGID environment variables PUID=${PUID:-963} PGID=${PGID:-963} -# If PUID is not 0 (root) +# Change the user and group IDs +groupmod -o -g "$PGID" nemo +usermod -o -u "$PUID" -g "$PGID" nemo if [ -n "$PUID" ]; then - if [ -n "$PGID" ]; then - groupmod -g "$PGID" nemo - fi - # Change the user and group IDs - usermod -u "$PUID" -g "$PGID" nemo # Change the ownership of the application directory chown -R nemo:nemo /nemo chown -R root:nemo /etc/gunicorn_configuration.py - NEMO_USER=nemo -else - NEMO_USER=root fi -echo "Running NEMO as user '$(id $NEMO_USER)'" +echo "Running NEMO as user '$(id nemo)'" # Collect static files -su "${NEMO_USER}" -c "django-admin collectstatic --no-input --clear" +su nemo -c "django-admin collectstatic --no-input --clear" # Run migrations to create or update the database -su "${NEMO_USER}" -c "django-admin migrate" +su nemo -c "django-admin migrate" # Run NEMO -su "${NEMO_USER}" -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" +su nemo -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" From be64c08097017d97135870128165a0c702f125db Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sun, 20 Apr 2025 00:57:14 +0200 Subject: [PATCH 6/9] Docker non-root: fixed SIGKILL forwarding to child processes. --- start_NEMO_in_Docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index 2ff7c278b..18a8e0ce6 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -29,4 +29,4 @@ su nemo -c "django-admin collectstatic --no-input --clear" su nemo -c "django-admin migrate" # Run NEMO -su nemo -c "exec gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" +exec su nemo -c "gunicorn --config=/etc/gunicorn_configuration.py NEMO.wsgi:application" From 9e8964a45b6a1d268d4b7f4bdc793aaa9e11eab8 Mon Sep 17 00:00:00 2001 From: r-xyz <100710244+r-xyz@users.noreply.github.com> Date: Sun, 20 Apr 2025 01:11:58 +0200 Subject: [PATCH 7/9] Splash Pad: Fix signaling to child processes. --- Dockerfile.splash_pad | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Dockerfile.splash_pad b/Dockerfile.splash_pad index 77ac9f7fc..7f738c6d6 100644 --- a/Dockerfile.splash_pad +++ b/Dockerfile.splash_pad @@ -41,5 +41,13 @@ WORKDIR /nemo ENV REMOTE_USER="captain" EXPOSE 8000/tcp +COPY --chmod=755 < Date: Sun, 20 Apr 2025 01:14:20 +0200 Subject: [PATCH 8/9] Splash Pad: run as non-root by default. --- Dockerfile.splash_pad | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Dockerfile.splash_pad b/Dockerfile.splash_pad index 7f738c6d6..14498954f 100644 --- a/Dockerfile.splash_pad +++ b/Dockerfile.splash_pad @@ -41,13 +41,24 @@ WORKDIR /nemo ENV REMOTE_USER="captain" EXPOSE 8000/tcp +# Non-root user +RUN addgroup --system --gid 963 nemo && \ + adduser --system --home /home/nemo --shell /usr/bin/bash --gid 963 --uid 963 --comment "NEMO user" nemo +RUN chown -R nemo:nemo /nemo +RUN chown -R nemo:nemo /var/run/ +ENV PGID=963 +ENV PUID=963 + COPY --chmod=755 < Date: Mon, 5 May 2025 18:57:36 +0200 Subject: [PATCH 9/9] Rootless Docker: removed unnecessary permission change for gunicorn. --- start_NEMO_in_Docker.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/start_NEMO_in_Docker.sh b/start_NEMO_in_Docker.sh index 18a8e0ce6..c073df1bc 100755 --- a/start_NEMO_in_Docker.sh +++ b/start_NEMO_in_Docker.sh @@ -18,7 +18,6 @@ usermod -o -u "$PUID" -g "$PGID" nemo if [ -n "$PUID" ]; then # Change the ownership of the application directory chown -R nemo:nemo /nemo - chown -R root:nemo /etc/gunicorn_configuration.py fi echo "Running NEMO as user '$(id nemo)'"