From 56a92e5c0e7643eaed0ed6b1ce74295912eeeff2 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 09:04:37 +1000 Subject: [PATCH] Run as root by default Optionally run as another user/group only if the env vars are specified. Should give flexibility to those who need to run processes as root and open ports without having to request additional priveleges --- docker/docker-compose.ci.yml | 2 ++ docker/rootfs/bin/common.sh | 13 +++++++ .../rootfs/etc/s6-overlay/s6-rc.d/backend/run | 26 +++++++++----- .../etc/s6-overlay/s6-rc.d/frontend/run | 16 ++++++--- .../rootfs/etc/s6-overlay/s6-rc.d/nginx/run | 10 ++++-- .../s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 36 +++++++++---------- .../s6-rc.d/prepare/30-ownership.sh | 22 ++++++------ .../s6-overlay/s6-rc.d/prepare/90-banner.sh | 12 ++++--- 8 files changed, 87 insertions(+), 50 deletions(-) diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index c090e19c..9f4edc00 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -33,6 +33,8 @@ services: LE_STAGING: 'true' FORCE_COLOR: 1 DB_SQLITE_FILE: '/data/mydb.sqlite' + PUID: 1000 + PGID: 1000 volumes: - npm_data:/data expose: diff --git a/docker/rootfs/bin/common.sh b/docker/rootfs/bin/common.sh index b95ff941..0bc6468d 100644 --- a/docker/rootfs/bin/common.sh +++ b/docker/rootfs/bin/common.sh @@ -9,6 +9,19 @@ RED='\E[1;31m' RESET='\E[0m' export CYAN BLUE YELLOW RED RESET +PUID=${PUID:-0} +PGID=${PGID:-0} + +if [[ "$PUID" -ne '0' ]] && [ "$PGID" = '0' ]; then + # set group id to same as user id, + # the user probably forgot to specify the group id and + # it would be rediculous to intentionally use the root group + # for a non-root user + PGID=$PUID +fi + +export PUID PGID + log_info () { echo -e "${BLUE}❯ ${CYAN}$1${RESET}" } diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run index b8287643..2f9fa9f6 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -5,18 +5,28 @@ set -e . /bin/common.sh -log_info 'Starting backend ...' +cd /app || exit 1 -if [ "$DEVELOPMENT" == "true" ]; then - cd /app || exit 1 - # If yarn install fails: add --verbose --network-concurrency 1 - s6-setuidgid npmuser yarn install - exec s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js' +if [ "${DEVELOPMENT:-}" = "true" ]; then + if [ "$PUID" = '0' ]; then + log_info 'Starting backend development ...' + yarn install + node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js + else + log_info "Starting backend development as npmuser ($PUID) ..." + s6-setuidgid npmuser yarn install + exec s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js' + fi else - cd /app || exit 1 while : do - s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --abort_on_uncaught_exception --max_old_space_size=250 index.js' + if [ "$PUID" = '0' ]; then + log_info 'Starting backend ...' + node --abort_on_uncaught_exception --max_old_space_size=250 index.js + else + log_info "Starting backend as npmuser ($PUID) ..." + s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --abort_on_uncaught_exception --max_old_space_size=250 index.js' + fi sleep 1 done fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run index 7a80c25a..19db5733 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run @@ -8,14 +8,20 @@ set -e if [ "$DEVELOPMENT" == "true" ]; then . /bin/common.sh cd /app/frontend || exit 1 - log_info 'Starting frontend ...' HOME=/tmp/npmuserhome export HOME mkdir -p /app/frontend/dist - chown -R npmuser:npmuser /app/frontend/dist - # If yarn install fails: add --verbose --network-concurrency 1 - s6-setuidgid npmuser yarn install - exec s6-setuidgid npmuser yarn watch + chown -R "$PUID:$PGID" /app/frontend/dist + + if [ "$PUID" = '0' ]; then + log_info 'Starting frontend ...' + yarn install + exec yarn watch + else + log_info "Starting frontend as npmuser ($PUID) ..." + s6-setuidgid npmuser yarn install + exec s6-setuidgid npmuser yarn watch + fi else exit 0 fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run index 044e4d30..30f3a71a 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -5,6 +5,10 @@ set -e . /bin/common.sh -log_info 'Starting nginx ...' - -exec s6-setuidgid npmuser nginx +if [ "$PUID" = '0' ]; then + log_info 'Starting nginx ...' + exec nginx +else + log_info "Starting nginx as npmuser ($PUID) ..." + exec s6-setuidgid npmuser nginx +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh index f8da7b8c..14dd6d28 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh @@ -3,23 +3,23 @@ set -e -PUID=${PUID:-911} -PGID=${PGID:-911} - -log_info 'Configuring npmuser ...' - -groupmod -g 1000 users || exit 1 - -if id -u npmuser; then - # user already exists - usermod -u "${PUID}" npmuser || exit 1 +if [ "$PUID" = '0' ]; then + log_info 'Skipping npmuser configuration' else - # Add npmuser user - useradd -u "${PUID}" -U -d /tmp/npmuserhome -s /bin/false npmuser || exit 1 -fi + log_info 'Configuring npmuser ...' + groupmod -g 1000 users || exit 1 -usermod -G users npmuser || exit 1 -groupmod -o -g "${PGID}" npmuser || exit 1 -# Home for npmuser -mkdir -p /tmp/npmuserhome -chown -R npmuser:npmuser /tmp/npmuserhome + if id -u npmuser; then + # user already exists + usermod -u "$PUID" npmuser || exit 1 + else + # Add npmuser user + useradd -u "$PUID" -U -d /tmp/npmuserhome -s /bin/false npmuser || exit 1 + fi + + usermod -G users npmuser || exit 1 + groupmod -o -g "$PGID" npmuser || exit 1 + # Home for npmuser + mkdir -p /tmp/npmuserhome + chown -R npmuser:npmuser /tmp/npmuserhome +fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh index 3f5c481d..684166e1 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh @@ -9,16 +9,16 @@ log_info 'Setting ownership ...' chown root /tmp/nginx # npmuser -chown -R npmuser:npmuser /data -chown -R npmuser:npmuser /etc/letsencrypt -chown -R npmuser:npmuser /run/nginx -chown -R npmuser:npmuser /tmp/nginx -chown -R npmuser:npmuser /var/cache/nginx -chown -R npmuser:npmuser /var/lib/logrotate -chown -R npmuser:npmuser /var/lib/nginx -chown -R npmuser:npmuser /var/log/nginx +chown -R "$PUID:$PGID" /data \ + /etc/letsencrypt \ + /run/nginx \ + /tmp/nginx \ + /var/cache/nginx \ + /var/lib/logrotate \ + /var/lib/nginx \ + /var/log/nginx # Don't chown entire /etc/nginx folder as this causes crashes on some systems -chown -R npmuser:npmuser /etc/nginx/nginx -chown -R npmuser:npmuser /etc/nginx/nginx.conf -chown -R npmuser:npmuser /etc/nginx/conf.d +chown -R "$PUID:$PGID" /etc/nginx/nginx \ + /etc/nginx/nginx.conf \ + /etc/nginx/conf.d diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh index af51b46d..ae3ad00f 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh @@ -10,8 +10,10 @@ echo "------------------------------------- | \| | |_) | |\/| | | |\ | __/| | | | |_| \_|_| |_| |_| -------------------------------------- -User UID: $(id -u npmuser) -User GID: $(id -g npmuser) -------------------------------------- -" +-------------------------------------" +if [[ "$PUID" -ne '0' ]]; then + echo "User UID: $(id -u npmuser)" + echo "User GID: $(id -g npmuser)" + echo "-------------------------------------" +fi +echo