From 61b290e22034cdccde96a68c405fff54aff2e1ae Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 28 Mar 2023 08:49:58 +1000 Subject: [PATCH 001/334] Chown each folder on separately Really not sure why this fixes #2734 however it does actually help the ownership script succeed specifically on arm7/raspbian --- .../s6-rc.d/prepare/30-ownership.sh | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) 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 f415979eb..ea4551123 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,13 +9,12 @@ log_info 'Setting ownership ...' chown root /tmp/nginx # npmuser -chown -R npmuser:npmuser \ - /data \ - /etc/letsencrypt \ - /etc/nginx \ - /run/nginx \ - /tmp/nginx \ - /var/cache/nginx \ - /var/lib/logrotate \ - /var/lib/nginx \ - /var/log/nginx +chown -R npmuser:npmuser /data +chown -R npmuser:npmuser /etc/letsencrypt +chown -R npmuser:npmuser /etc/nginx +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 From 35abb4d7ae4334122d634c4f9e51b1f0531425e9 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 28 Mar 2023 09:33:30 +1000 Subject: [PATCH 002/334] Execute permissions missing on script --- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh old mode 100644 new mode 100755 From d179887c15ac0d8a7822da7b6be36ae5055ef419 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 28 Mar 2023 10:39:26 +1000 Subject: [PATCH 003/334] Another fix for #2734, only chown parts of /etc/nginx --- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 ea4551123..3eddafdab 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 @@ -11,10 +11,13 @@ chown root /tmp/nginx # npmuser chown -R npmuser:npmuser /data chown -R npmuser:npmuser /etc/letsencrypt -chown -R npmuser:npmuser /etc/nginx 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 + +# Don't chown entire /etc/nginx folder as this causes crashes on some systems +chown -R npmuser:npmuser /etc/nginx/nginx.conf +chown -R npmuser:npmuser /etc/nginx/conf.d From 7f5e0414ac05fc9c3ad834fed083033cbdfce50e Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 29 Mar 2023 07:22:15 +1000 Subject: [PATCH 004/334] Bump version --- .version | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.version b/.version index 10c2c0c3d..8bbb6e406 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.10.0 +2.10.1 diff --git a/README.md b/README.md index e74e6cc29..d5a7473f9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@



- + From 91cf3c887394864a388f52c956933f197fbc8b8c Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 29 Mar 2023 08:24:28 +1000 Subject: [PATCH 005/334] Tweaks to docker compose ci after updates --- Jenkinsfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 2385aef59..cb597eba2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -90,13 +90,13 @@ pipeline { steps { // Bring up a stack sh 'docker-compose up -d fullstack-sqlite' - sh './scripts/wait-healthy $(docker-compose ps -q fullstack-sqlite) 120' + sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-sqlite) 120' // Run tests sh 'rm -rf test/results' sh 'docker-compose up cypress-sqlite' // Get results - sh 'docker cp -L "$(docker-compose ps -q cypress-sqlite):/test/results" test/' + sh 'docker cp -L "$(docker-compose ps --all -q cypress-sqlite):/test/results" test/' } post { always { @@ -116,13 +116,13 @@ pipeline { steps { // Bring up a stack sh 'docker-compose up -d fullstack-mysql' - sh './scripts/wait-healthy $(docker-compose ps -q fullstack-mysql) 120' + sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-mysql) 120' // Run tests sh 'rm -rf test/results' sh 'docker-compose up cypress-mysql' // Get results - sh 'docker cp -L "$(docker-compose ps -q cypress-mysql):/test/results" test/' + sh 'docker cp -L "$(docker-compose ps --all -q cypress-mysql):/test/results" test/' } post { always { From d5ed70dbb652a7e37a56e3be651cfd8b9c4dfe11 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 29 Mar 2023 14:03:58 +1000 Subject: [PATCH 006/334] Own this nginx folder too --- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 1 + 1 file changed, 1 insertion(+) 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 3eddafdab..3f5c481d5 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 @@ -19,5 +19,6 @@ chown -R npmuser:npmuser /var/lib/nginx chown -R npmuser:npmuser /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 From 9d672f581313d4c1b93d713681d9dc10f8eb471c Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 29 Mar 2023 14:03:58 +1000 Subject: [PATCH 007/334] Own this nginx folder too --- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 1 + 1 file changed, 1 insertion(+) 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 3eddafdab..3f5c481d5 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 @@ -19,5 +19,6 @@ chown -R npmuser:npmuser /var/lib/nginx chown -R npmuser:npmuser /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 From 56a92e5c0e7643eaed0ed6b1ce74295912eeeff2 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 09:04:37 +1000 Subject: [PATCH 008/334] 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 | 34 +++++++++---------- .../s6-rc.d/prepare/30-ownership.sh | 22 ++++++------ .../s6-overlay/s6-rc.d/prepare/90-banner.sh | 12 ++++--- 8 files changed, 86 insertions(+), 49 deletions(-) diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index c090e19c9..9f4edc00e 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 b95ff9417..0bc6468d3 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 b82876433..2f9fa9f64 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 7a80c25a3..19db57338 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 044e4d30a..30f3a71ab 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 f8da7b8c8..14dd6d28d 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 ...' +if [ "$PUID" = '0' ]; then + log_info 'Skipping npmuser configuration' +else + log_info 'Configuring npmuser ...' + groupmod -g 1000 users || exit 1 -groupmod -g 1000 users || exit 1 + 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 -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 + 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 - -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 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 3f5c481d5..684166e13 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 af51b46da..ae3ad00ff 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 From dad8561ea15beb43d047eaca01217de7abdd387e Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 10:20:20 +1000 Subject: [PATCH 009/334] Use numbers for permissions in case npmuser doesn't exist --- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 2 +- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 14dd6d28d..a749ca2b7 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 @@ -21,5 +21,5 @@ else groupmod -o -g "$PGID" npmuser || exit 1 # Home for npmuser mkdir -p /tmp/npmuserhome - chown -R npmuser:npmuser /tmp/npmuserhome + chown -R "$PUID:$PGID" /tmp/npmuserhome fi diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh index bcd64d25d..bc27eb145 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh @@ -29,7 +29,7 @@ process_folder () { done # ensure the files are still owned by the npmuser - chown -R npmuser:npmuser "$1" + chown -R "$PUID:$PGID" "$1" } process_folder /etc/nginx/conf.d From 4a86bb42cc9a44c8d0a48b5ecd9f7290a47401d3 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 11:19:16 +1000 Subject: [PATCH 010/334] Different approach, always create npmuser even if the user id is zero, and then we'll always use it --- docker/rootfs/etc/nginx/nginx.conf | 1 + .../rootfs/etc/s6-overlay/s6-rc.d/backend/run | 23 ++++---------- .../etc/s6-overlay/s6-rc.d/frontend/run | 14 +++------ .../rootfs/etc/s6-overlay/s6-rc.d/nginx/run | 9 ++---- .../s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 31 ++++++++----------- .../s6-overlay/s6-rc.d/prepare/90-banner.sh | 16 +++++----- 6 files changed, 33 insertions(+), 61 deletions(-) diff --git a/docker/rootfs/etc/nginx/nginx.conf b/docker/rootfs/etc/nginx/nginx.conf index 438c1bd49..c2ee97cce 100644 --- a/docker/rootfs/etc/nginx/nginx.conf +++ b/docker/rootfs/etc/nginx/nginx.conf @@ -1,6 +1,7 @@ # run nginx in foreground daemon off; pid /run/nginx/nginx.pid; +user npmuser; # Set number of worker processes automatically based on number of CPU cores. worker_processes auto; 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 2f9fa9f64..e8ffa17c3 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -7,26 +7,15 @@ set -e cd /app || exit 1 -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 +log_info 'Starting backend ...' + +if [ "${DEVELOPMENT:-}" = 'true' ]; then + 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' else while : do - 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 + s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --abort_on_uncaught_exception --max_old_space_size=250 index.js' 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 19db57338..1181c53e4 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frontend/run @@ -5,7 +5,7 @@ set -e # This service is DEVELOPMENT only. -if [ "$DEVELOPMENT" == "true" ]; then +if [ "$DEVELOPMENT" = 'true' ]; then . /bin/common.sh cd /app/frontend || exit 1 HOME=/tmp/npmuserhome @@ -13,15 +13,9 @@ if [ "$DEVELOPMENT" == "true" ]; then mkdir -p /app/frontend/dist 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 + log_info 'Starting frontend ...' + s6-setuidgid npmuser yarn install + exec s6-setuidgid npmuser yarn watch 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 30f3a71ab..fa8c1fc50 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -5,10 +5,5 @@ set -e . /bin/common.sh -if [ "$PUID" = '0' ]; then - log_info 'Starting nginx ...' - exec nginx -else - log_info "Starting nginx as npmuser ($PUID) ..." - exec s6-setuidgid npmuser nginx -fi +log_info 'Starting nginx ...' +exec s6-setuidgid npmuser nginx 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 a749ca2b7..c5cf54355 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,18 @@ set -e -if [ "$PUID" = '0' ]; then - log_info 'Skipping npmuser configuration' -else - log_info 'Configuring npmuser ...' - groupmod -g 1000 users || exit 1 - - 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 +log_info 'Configuring npmuser ...' - usermod -G users npmuser || exit 1 - groupmod -o -g "$PGID" npmuser || exit 1 - # Home for npmuser - mkdir -p /tmp/npmuserhome - chown -R "$PUID:$PGID" /tmp/npmuserhome +if id -u npmuser; then + # user already exists + usermod -u "$PUID" npmuser || exit 1 +else + # Add npmuser user + useradd -o -u "$PUID" -U -d /tmp/npmuserhome -s /bin/false npmuser || exit 1 fi + +usermod -G "$PGID" npmuser || exit 1 +groupmod -o -g "$PGID" npmuser || exit 1 +# Home for npmuser +mkdir -p /tmp/npmuserhome +chown -R "$PUID:$PGID" /tmp/npmuserhome 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 ae3ad00ff..7991ddf4f 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 @@ -3,17 +3,15 @@ set -e -echo -echo "------------------------------------- +echo " +------------------------------------- _ _ ____ __ __ | \ | | _ \| \/ | | \| | |_) | |\/| | | |\ | __/| | | | |_| \_|_| |_| |_| --------------------------------------" -if [[ "$PUID" -ne '0' ]]; then - echo "User UID: $(id -u npmuser)" - echo "User GID: $(id -g npmuser)" - echo "-------------------------------------" -fi -echo +------------------------------------- +User ID: $PUID +Group ID: $PGID +------------------------------------- +" From 5d03ede100d74aed2f441ee7e17c1c56a496966f Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 12:44:28 +1000 Subject: [PATCH 011/334] Add test for creating a host --- backend/doc/api.swagger.json | 586 ++++++++++++++------- test/cypress/integration/api/Hosts.spec.js | 48 ++ 2 files changed, 442 insertions(+), 192 deletions(-) create mode 100644 test/cypress/integration/api/Hosts.spec.js diff --git a/backend/doc/api.swagger.json b/backend/doc/api.swagger.json index 06c025648..3fa19fc4b 100644 --- a/backend/doc/api.swagger.json +++ b/backend/doc/api.swagger.json @@ -40,6 +40,210 @@ } } }, + "/nginx/proxy-hosts": { + "get": { + "operationId": "getProxyHosts", + "summary": "Get all proxy hosts", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "query", + "name": "expand", + "description": "Expansions", + "schema": { + "type": "string", + "enum": ["access_list", "owner", "certificate"] + } + } + ], + "responses": { + "200": { + "description": "200 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": [ + { + "id": 1, + "created_on": "2023-03-30T01:12:23.000Z", + "modified_on": "2023-03-30T02:15:40.000Z", + "owner_user_id": 1, + "domain_names": ["aasdasdad"], + "forward_host": "asdasd", + "forward_port": 80, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": 0, + "caching_enabled": 0, + "block_exploits": 0, + "advanced_config": "sdfsdfsdf", + "meta": { + "letsencrypt_agree": false, + "dns_challenge": false, + "nginx_online": false, + "nginx_err": "Command failed: /usr/sbin/nginx -t -g \"error_log off;\"\nnginx: [emerg] unknown directive \"sdfsdfsdf\" in /data/nginx/proxy_host/1.conf:37\nnginx: configuration file /etc/nginx/nginx.conf test failed\n" + }, + "allow_websocket_upgrade": 0, + "http2_support": 0, + "forward_scheme": "http", + "enabled": 1, + "locations": [], + "hsts_enabled": 0, + "hsts_subdomains": 0, + "owner": { + "id": 1, + "created_on": "2023-03-30T01:11:50.000Z", + "modified_on": "2023-03-30T01:11:50.000Z", + "is_deleted": 0, + "is_disabled": 0, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "Admin", + "avatar": "", + "roles": ["admin"] + }, + "access_list": null, + "certificate": null + }, + { + "id": 2, + "created_on": "2023-03-30T02:11:49.000Z", + "modified_on": "2023-03-30T02:11:49.000Z", + "owner_user_id": 1, + "domain_names": ["test.example.com"], + "forward_host": "1.1.1.1", + "forward_port": 80, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": 0, + "caching_enabled": 0, + "block_exploits": 0, + "advanced_config": "", + "meta": { + "letsencrypt_agree": false, + "dns_challenge": false, + "nginx_online": true, + "nginx_err": null + }, + "allow_websocket_upgrade": 0, + "http2_support": 0, + "forward_scheme": "http", + "enabled": 1, + "locations": [], + "hsts_enabled": 0, + "hsts_subdomains": 0, + "owner": { + "id": 1, + "created_on": "2023-03-30T01:11:50.000Z", + "modified_on": "2023-03-30T01:11:50.000Z", + "is_deleted": 0, + "is_disabled": 0, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "Admin", + "avatar": "", + "roles": ["admin"] + }, + "access_list": null, + "certificate": null + } + ] + } + }, + "schema": { + "$ref": "#/components/schemas/ProxyHostsList" + } + } + } + } + } + }, + "post": { + "operationId": "createProxyHost", + "summary": "Create a Proxy Host", + "tags": ["Proxy Hosts"], + "security": [ + { + "BearerAuth": ["users"] + } + ], + "parameters": [ + { + "in": "body", + "name": "proxyhost", + "description": "Proxy Host Payload", + "required": true, + "schema": { + "$ref": "#/components/schemas/ProxyHostObject" + } + } + ], + "responses": { + "201": { + "description": "201 response", + "content": { + "application/json": { + "examples": { + "default": { + "value": { + "id": 3, + "created_on": "2023-03-30T02:31:27.000Z", + "modified_on": "2023-03-30T02:31:27.000Z", + "owner_user_id": 1, + "domain_names": ["test2.example.com"], + "forward_host": "1.1.1.1", + "forward_port": 80, + "access_list_id": 0, + "certificate_id": 0, + "ssl_forced": 0, + "caching_enabled": 0, + "block_exploits": 0, + "advanced_config": "", + "meta": { + "letsencrypt_agree": false, + "dns_challenge": false + }, + "allow_websocket_upgrade": 0, + "http2_support": 0, + "forward_scheme": "http", + "enabled": 1, + "locations": [], + "hsts_enabled": 0, + "hsts_subdomains": 0, + "certificate": null, + "owner": { + "id": 1, + "created_on": "2023-03-30T01:11:50.000Z", + "modified_on": "2023-03-30T01:11:50.000Z", + "is_deleted": 0, + "is_disabled": 0, + "email": "admin@example.com", + "name": "Administrator", + "nickname": "Admin", + "avatar": "", + "roles": ["admin"] + }, + "access_list": null, + "use_default_location": true, + "ipv6": true + } + } + }, + "schema": { + "$ref": "#/components/schemas/ProxyHostObject" + } + } + } + } + } + } + }, "/schema": { "get": { "operationId": "schema", @@ -55,14 +259,10 @@ "get": { "operationId": "refreshToken", "summary": "Refresh your access token", - "tags": [ - "Tokens" - ], + "tags": ["Tokens"], "security": [ { - "BearerAuth": [ - "tokens" - ] + "BearerAuth": ["tokens"] } ], "responses": { @@ -104,19 +304,14 @@ "scope": { "minLength": 1, "type": "string", - "enum": [ - "user" - ] + "enum": ["user"] }, "secret": { "minLength": 1, "type": "string" } }, - "required": [ - "identity", - "secret" - ], + "required": ["identity", "secret"], "type": "object" } } @@ -144,23 +339,17 @@ } }, "summary": "Request a new access token from credentials", - "tags": [ - "Tokens" - ] + "tags": ["Tokens"] } }, "/settings": { "get": { "operationId": "getSettings", "summary": "Get all settings", - "tags": [ - "Settings" - ], + "tags": ["Settings"], "security": [ { - "BearerAuth": [ - "settings" - ] + "BearerAuth": ["settings"] } ], "responses": { @@ -194,14 +383,10 @@ "get": { "operationId": "getSetting", "summary": "Get a setting", - "tags": [ - "Settings" - ], + "tags": ["Settings"], "security": [ { - "BearerAuth": [ - "settings" - ] + "BearerAuth": ["settings"] } ], "parameters": [ @@ -244,14 +429,10 @@ "put": { "operationId": "updateSetting", "summary": "Update a setting", - "tags": [ - "Settings" - ], + "tags": ["Settings"], "security": [ { - "BearerAuth": [ - "settings" - ] + "BearerAuth": ["settings"] } ], "parameters": [ @@ -305,14 +486,10 @@ "get": { "operationId": "getUsers", "summary": "Get all users", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -322,9 +499,7 @@ "description": "Expansions", "schema": { "type": "string", - "enum": [ - "permissions" - ] + "enum": ["permissions"] } } ], @@ -345,9 +520,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": [ - "admin" - ] + "roles": ["admin"] } ] }, @@ -362,9 +535,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": [ - "admin" - ], + "roles": ["admin"], "permissions": { "visibility": "all", "proxy_hosts": "manage", @@ -389,14 +560,10 @@ "post": { "operationId": "createUser", "summary": "Create a User", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -426,9 +593,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": [ - "admin" - ], + "roles": ["admin"], "permissions": { "visibility": "all", "proxy_hosts": "manage", @@ -454,14 +619,10 @@ "get": { "operationId": "getUser", "summary": "Get a user", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -501,9 +662,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": [ - "admin" - ] + "roles": ["admin"] } } }, @@ -518,14 +677,10 @@ "put": { "operationId": "updateUser", "summary": "Update a User", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -574,9 +729,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?default=mm", - "roles": [ - "admin" - ] + "roles": ["admin"] } } }, @@ -591,14 +744,10 @@ "delete": { "operationId": "deleteUser", "summary": "Delete a User", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -637,14 +786,10 @@ "put": { "operationId": "updateUserAuth", "summary": "Update a User's Authentication", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -700,14 +845,10 @@ "put": { "operationId": "updateUserPermissions", "summary": "Update a User's Permissions", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -755,14 +896,10 @@ "put": { "operationId": "loginAsUser", "summary": "Login as this user", - "tags": [ - "Users" - ], + "tags": ["Users"], "security": [ { - "BearerAuth": [ - "users" - ] + "BearerAuth": ["users"] } ], "parameters": [ @@ -797,9 +934,7 @@ "name": "Jamie Curnow", "nickname": "James", "avatar": "//www.gravatar.com/avatar/3c8d73f45fd8763f827b964c76e6032a?default=mm", - "roles": [ - "admin" - ] + "roles": ["admin"] } } } @@ -807,11 +942,7 @@ "schema": { "type": "object", "description": "Login object", - "required": [ - "expires", - "token", - "user" - ], + "required": ["expires", "token", "user"], "additionalProperties": false, "properties": { "expires": { @@ -840,14 +971,10 @@ "get": { "operationId": "reportsHosts", "summary": "Report on Host Statistics", - "tags": [ - "Reports" - ], + "tags": ["Reports"], "security": [ { - "BearerAuth": [ - "reports" - ] + "BearerAuth": ["reports"] } ], "responses": { @@ -878,14 +1005,10 @@ "get": { "operationId": "getAuditLog", "summary": "Get Audit Log", - "tags": [ - "Audit Log" - ], + "tags": ["Audit Log"], "security": [ { - "BearerAuth": [ - "audit-log" - ] + "BearerAuth": ["audit-log"] } ], "responses": { @@ -925,10 +1048,7 @@ "type": "object", "description": "Health object", "additionalProperties": false, - "required": [ - "status", - "version" - ], + "required": ["status", "version"], "properties": { "status": { "type": "string", @@ -944,11 +1064,7 @@ "revision": 0 }, "additionalProperties": false, - "required": [ - "major", - "minor", - "revision" - ], + "required": ["major", "minor", "revision"], "properties": { "major": { "type": "integer", @@ -969,10 +1085,7 @@ "TokenObject": { "type": "object", "description": "Token object", - "required": [ - "expires", - "token" - ], + "required": ["expires", "token"], "additionalProperties": false, "properties": { "expires": { @@ -988,17 +1101,148 @@ } } }, - "SettingObject": { + "ProxyHostObject": { "type": "object", - "description": "Setting object", + "description": "Proxy Host object", "required": [ "id", - "name", - "description", - "value", - "meta" + "created_on", + "modified_on", + "owner_user_id", + "domain_names", + "forward_host", + "forward_port", + "access_list_id", + "certificate_id", + "ssl_forced", + "caching_enabled", + "block_exploits", + "advanced_config", + "meta", + "allow_websocket_upgrade", + "http2_support", + "forward_scheme", + "enabled", + "locations", + "hsts_enabled", + "hsts_subdomains", + "certificate", + "use_default_location", + "ipv6" ], "additionalProperties": false, + "properties": { + "id": { + "type": "integer", + "description": "Proxy Host ID", + "minimum": 1, + "example": 1 + }, + "created_on": { + "type": "string", + "description": "Created Date", + "example": "2020-01-30T09:36:08.000Z" + }, + "modified_on": { + "type": "string", + "description": "Modified Date", + "example": "2020-01-30T09:41:04.000Z" + }, + "owner_user_id": { + "type": "integer", + "minimum": 1, + "example": 1 + }, + "domain_names": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "minLength": 1 + } + }, + "forward_host": { + "type": "string", + "minLength": 1 + }, + "forward_port": { + "type": "integer", + "minimum": 1 + }, + "access_list_id": { + "type": "integer" + }, + "certificate_id": { + "type": "integer" + }, + "ssl_forced": { + "type": "integer" + }, + "caching_enabled": { + "type": "integer" + }, + "block_exploits": { + "type": "integer" + }, + "advanced_config": { + "type": "string" + }, + "meta": { + "type": "object" + }, + "allow_websocket_upgrade": { + "type": "integer" + }, + "http2_support": { + "type": "integer" + }, + "forward_scheme": { + "type": "string" + }, + "enabled": { + "type": "integer" + }, + "locations": { + "type": "array" + }, + "hsts_enabled": { + "type": "integer" + }, + "hsts_subdomains": { + "type": "integer" + }, + "certificate": { + "type": "object", + "nullable": true + }, + "owner": { + "type": "object", + "nullable": true + }, + "access_list": { + "type": "object", + "nullable": true + }, + "use_default_location": { + "type": "boolean" + }, + "ipv6": { + "type": "boolean" + } + } + }, + "ProxyHostsList": { + "type": "array", + "description": "Proxyn Hosts list", + "items": { + "$ref": "#/components/schemas/ProxyHostObject" + } + }, + "SettingObject": { + "type": "object", + "description": "Setting object", + "required": ["id", "name", "description", "value", "meta"], + "additionalProperties": false, "properties": { "id": { "type": "string", @@ -1057,17 +1301,7 @@ "UserObject": { "type": "object", "description": "User object", - "required": [ - "id", - "created_on", - "modified_on", - "is_disabled", - "email", - "name", - "nickname", - "avatar", - "roles" - ], + "required": ["id", "created_on", "modified_on", "is_disabled", "email", "name", "nickname", "avatar", "roles"], "additionalProperties": false, "properties": { "id": { @@ -1117,9 +1351,7 @@ }, "roles": { "description": "Roles applied", - "example": [ - "admin" - ], + "example": ["admin"], "type": "array", "items": { "type": "string" @@ -1137,10 +1369,7 @@ "AuthObject": { "type": "object", "description": "Authentication Object", - "required": [ - "type", - "secret" - ], + "required": ["type", "secret"], "properties": { "type": { "type": "string", @@ -1167,64 +1396,37 @@ "visibility": { "type": "string", "description": "Visibility Type", - "enum": [ - "all", - "user" - ] + "enum": ["all", "user"] }, "access_lists": { "type": "string", "description": "Access Lists Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] }, "dead_hosts": { "type": "string", "description": "404 Hosts Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] }, "proxy_hosts": { "type": "string", "description": "Proxy Hosts Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] }, "redirection_hosts": { "type": "string", "description": "Redirection Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] }, "streams": { "type": "string", "description": "Streams Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] }, "certificates": { "type": "string", "description": "Certificates Permissions", - "enum": [ - "hidden", - "view", - "manage" - ] + "enum": ["hidden", "view", "manage"] } } }, @@ -1251,4 +1453,4 @@ } } } -} \ No newline at end of file +} diff --git a/test/cypress/integration/api/Hosts.spec.js b/test/cypress/integration/api/Hosts.spec.js new file mode 100644 index 000000000..4dffe31b7 --- /dev/null +++ b/test/cypress/integration/api/Hosts.spec.js @@ -0,0 +1,48 @@ +/// + +describe('Hosts endpoints', () => { + let token; + + before(() => { + cy.getToken().then((tok) => { + token = tok; + }); + }); + + it('Should be able to create a http host', function() { + cy.task('backendApiPost', { + token: token, + path: '/api/nginx/proxy-hosts', + data: { + domain_names: ['test.example.com'], + forward_scheme: 'http', + forward_host: '1.1.1.1', + forward_port: 80, + access_list_id: '0', + certificate_id: 0, + meta: { + letsencrypt_agree: false, + dns_challenge: false + }, + advanced_config: '', + locations: [], + block_exploits: false, + caching_enabled: false, + allow_websocket_upgrade: false, + http2_support: false, + hsts_enabled: false, + hsts_subdomains: false, + ssl_forced: false + } + }).then((data) => { + cy.validateSwaggerSchema('post', 201, '/nginx/proxy-hosts', data); + expect(data).to.have.property('id'); + expect(data.id).to.be.greaterThan(0); + expect(data).to.have.property('enabled'); + expect(data.enabled).to.be.greaterThan(0); + expect(data).to.have.property('meta'); + expect(data.meta.nginx_online).not.to.exist(); + }); + }); + +}); From 8a4a7d0caf0b88e62e8d329d4e0844fa032071c6 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 12:51:26 +1000 Subject: [PATCH 012/334] Allow 201 as success in test result --- test/cypress/plugins/backendApi/client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/plugins/backendApi/client.js b/test/cypress/plugins/backendApi/client.js index 4de398186..29684cfdc 100644 --- a/test/cypress/plugins/backendApi/client.js +++ b/test/cypress/plugins/backendApi/client.js @@ -126,7 +126,7 @@ BackendApi.prototype._putPostJson = function(fn, path, data, returnOnError) { logger('Response data:', data); if (!returnOnError && data instanceof Error) { reject(data); - } else if (!returnOnError && response.statusCode != 200) { + } else if (!returnOnError && (response.statusCode < 200 || response.statusCode >= 300)) { if (typeof data === 'object' && typeof data.error === 'object' && typeof data.error.message !== 'undefined') { reject(new Error(data.error.code + ': ' + data.error.message)); } else { From 308a7149ede7b10786ca04489d933ffcb99bb901 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 12:55:20 +1000 Subject: [PATCH 013/334] Tweak test --- test/cypress/integration/api/Hosts.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/api/Hosts.spec.js b/test/cypress/integration/api/Hosts.spec.js index 4dffe31b7..a25c7d95b 100644 --- a/test/cypress/integration/api/Hosts.spec.js +++ b/test/cypress/integration/api/Hosts.spec.js @@ -41,7 +41,7 @@ describe('Hosts endpoints', () => { expect(data).to.have.property('enabled'); expect(data.enabled).to.be.greaterThan(0); expect(data).to.have.property('meta'); - expect(data.meta.nginx_online).not.to.exist(); + expect(typeof data.meta.nginx_online).not.be.equal('undefined'); }); }); From 9225d5d442f269a5358b76fe9a1c441745d7150d Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 13:00:22 +1000 Subject: [PATCH 014/334] Tweak test --- test/cypress/integration/api/Hosts.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/api/Hosts.spec.js b/test/cypress/integration/api/Hosts.spec.js index a25c7d95b..4652c8e08 100644 --- a/test/cypress/integration/api/Hosts.spec.js +++ b/test/cypress/integration/api/Hosts.spec.js @@ -41,7 +41,7 @@ describe('Hosts endpoints', () => { expect(data).to.have.property('enabled'); expect(data.enabled).to.be.greaterThan(0); expect(data).to.have.property('meta'); - expect(typeof data.meta.nginx_online).not.be.equal('undefined'); + expect(typeof data.meta.nginx_online).to.be.equal('undefined'); }); }); From eb2e2e0478609dbbb32fffb36e0d88798a90b21c Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 14:44:15 +1000 Subject: [PATCH 015/334] Throw in a docker restart during testing phase --- Jenkinsfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index cb597eba2..9fd2ce21b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -91,10 +91,14 @@ pipeline { // Bring up a stack sh 'docker-compose up -d fullstack-sqlite' sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-sqlite) 120' + // Stop and Start it, as this will test it's ability to restart with existing data + sh 'docker-compose stop fullstack-sqlite' + sh 'docker-compose start fullstack-sqlite' + sh './scripts/wait-healthy $(docker-compose ps --all -q fullstack-sqlite) 120' // Run tests sh 'rm -rf test/results' - sh 'docker-compose up cypress-sqlite' + sh 'docker-compose` cypress-sqlite' // Get results sh 'docker cp -L "$(docker-compose ps --all -q cypress-sqlite):/test/results" test/' } From d9b9af543e33439e8d4758b9c8dbff46b0853307 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 15:03:57 +1000 Subject: [PATCH 016/334] Fix text replacement whoops --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9fd2ce21b..862b24704 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -98,7 +98,7 @@ pipeline { // Run tests sh 'rm -rf test/results' - sh 'docker-compose` cypress-sqlite' + sh 'docker-compose up cypress-sqlite' // Get results sh 'docker cp -L "$(docker-compose ps --all -q cypress-sqlite):/test/results" test/' } From 9fe07fa6c328a4e756480adffc19ca8ed82da1ff Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 30 Mar 2023 15:37:59 +1000 Subject: [PATCH 017/334] Update documentation --- docs/advanced-config/README.md | 21 +++++++++++++++++++++ docs/setup/README.md | 5 +---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/advanced-config/README.md b/docs/advanced-config/README.md index 7cb8a3a95..a0acdda18 100644 --- a/docs/advanced-config/README.md +++ b/docs/advanced-config/README.md @@ -1,5 +1,26 @@ # Advanced Configuration +## Running processes as a user/group + +By default, the services (nginx etc) will run as `root` user inside the docker container. +You can change this behaviour by setting the following environment variables. +Not only will they run the services as this user/group, they will change the ownership +on the `data` and `letsencrypt` folders at startup. + +```yml +services: + app: + image: 'jc21/nginx-proxy-manager:latest' + environment: + PUID: 1000 + PGID: 1000 + # ... +``` + +This may have the side effect of a failed container start due to permission denied trying +to open port 80 on some systems. The only course to fix that is to remove the variables +and run as the default root user. + ## Best Practice: Use a Docker network For those who have a few of their upstream services running in Docker on the same Docker diff --git a/docs/setup/README.md b/docs/setup/README.md index a78d79e48..032b714cf 100644 --- a/docs/setup/README.md +++ b/docs/setup/README.md @@ -64,9 +64,6 @@ services: # Add any other Stream port you want to expose # - '21:21' # FTP environment: - # Unix user and group IDs, optional - PUID: 1000 - PGID: 1000 # Mysql/Maria connection parameters: DB_MYSQL_HOST: "db" DB_MYSQL_PORT: 3306 @@ -90,7 +87,7 @@ services: MYSQL_USER: 'npm' MYSQL_PASSWORD: 'npm' volumes: - - ./data/mysql:/var/lib/mysql + - ./mysql:/var/lib/mysql ``` ::: warning From ddf80302c6b3a5ddf2c3ce29da3c4d976e2bff1d Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Fri, 31 Mar 2023 08:25:45 +1000 Subject: [PATCH 018/334] Bump version --- .version | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.version b/.version index 8bbb6e406..c6436a853 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.10.1 +2.10.2 diff --git a/README.md b/README.md index d5a7473f9..eefa11eb9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@



- + From db4ab1d548ab2d0b0bbe620034a9a48563ebd642 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 3 May 2023 16:01:27 +1000 Subject: [PATCH 019/334] Verbose debugging of s6 scripts --- docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run | 2 ++ docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 2 ++ docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh | 2 ++ .../rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 2 ++ docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh | 2 ++ docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 7 ++++++- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh | 2 ++ 7 files changed, 18 insertions(+), 1 deletion(-) 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 e8ffa17c3..9fe0831df 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x . /bin/common.sh 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 c5cf54355..1f290de1c 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 @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x log_info 'Configuring npmuser ...' diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh index 2f59ef41a..12f6400e9 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x log_info 'Checking paths ...' 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 684166e13..41da358be 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 @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x log_info 'Setting ownership ...' diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh index 0cb9f1264..d13fae7a8 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x log_info 'Dynamic resolvers ...' diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh index bc27eb145..3e583bfa4 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh @@ -1,8 +1,13 @@ -#!/bin/bash +#!/command/with-contenv bash +# shellcheck shell=bash # This command reads the `DISABLE_IPV6` env var and will either enable # or disable ipv6 in all nginx configs based on this setting. +set -e +# verbose +set -x + log_info 'IPv6 ...' # Lowercase diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh index faa22accb..1a7243820 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh @@ -2,6 +2,8 @@ # shellcheck shell=bash set -e +# verbose +set -x # in s6, environmental variables are written as text files for s6 to monitor # search through full-path filenames for files ending in "__FILE" From a1245bc16149fd487e21014b26fd2e28b88cc768 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 4 May 2023 08:27:38 +1000 Subject: [PATCH 020/334] Split up ownership to indentify point of failure --- .../s6-rc.d/prepare/30-ownership.sh | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) 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 41da358be..3c583ab3b 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 @@ -11,16 +11,16 @@ log_info 'Setting ownership ...' chown root /tmp/nginx # npmuser -chown -R "$PUID:$PGID" /data \ - /etc/letsencrypt \ - /run/nginx \ - /tmp/nginx \ - /var/cache/nginx \ - /var/lib/logrotate \ - /var/lib/nginx \ - /var/log/nginx +chown -R "$PUID:$PGID" /data +chown -R "$PUID:$PGID" /etc/letsencrypt +chown -R "$PUID:$PGID" /run/nginx +chown -R "$PUID:$PGID" /tmp/nginx +chown -R "$PUID:$PGID" /var/cache/nginx +chown -R "$PUID:$PGID" /var/lib/logrotate +chown -R "$PUID:$PGID" /var/lib/nginx +chown -R "$PUID:$PGID" /var/log/nginx # Don't chown entire /etc/nginx folder as this causes crashes on some systems -chown -R "$PUID:$PGID" /etc/nginx/nginx \ - /etc/nginx/nginx.conf \ - /etc/nginx/conf.d +chown -R "$PUID:$PGID" /etc/nginx/nginx +chown -R "$PUID:$PGID" /etc/nginx/nginx.conf +chown -R "$PUID:$PGID" /etc/nginx/conf.d From c432c34fb3117da32c04acd1ca7826e9d63e6c85 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 4 May 2023 10:03:06 +1000 Subject: [PATCH 021/334] Small refactor of user/groups and add checks during startup. Only use -x in bash scripts when DEBUG=true set in env vars --- docker/rootfs/bin/common.sh | 12 ++++++ docker/rootfs/etc/nginx/nginx.conf | 2 +- .../rootfs/etc/s6-overlay/s6-rc.d/backend/run | 6 +-- .../etc/s6-overlay/s6-rc.d/frontend/run | 6 +-- .../rootfs/etc/s6-overlay/s6-rc.d/nginx/run | 2 +- .../etc/s6-overlay/s6-rc.d/prepare/00-all.sh | 6 ++- .../s6-overlay/s6-rc.d/prepare/10-npmuser.sh | 22 ---------- .../s6-rc.d/prepare/10-usergroup.sh | 40 +++++++++++++++++++ .../s6-overlay/s6-rc.d/prepare/20-paths.sh | 2 - .../s6-rc.d/prepare/30-ownership.sh | 4 +- .../s6-overlay/s6-rc.d/prepare/40-dynamic.sh | 2 - .../etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | 4 +- .../s6-overlay/s6-rc.d/prepare/60-secrets.sh | 2 - .../s6-overlay/s6-rc.d/prepare/90-banner.sh | 5 ++- 14 files changed, 70 insertions(+), 45 deletions(-) delete mode 100755 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh create mode 100755 docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-usergroup.sh diff --git a/docker/rootfs/bin/common.sh b/docker/rootfs/bin/common.sh index 0bc6468d3..913dd3e17 100644 --- a/docker/rootfs/bin/common.sh +++ b/docker/rootfs/bin/common.sh @@ -12,6 +12,11 @@ export CYAN BLUE YELLOW RED RESET PUID=${PUID:-0} PGID=${PGID:-0} +NPMUSER=npm +NPMGROUP=npm +NPMHOME=/tmp/npmuserhome +export NPMUSER NPMGROUP NPMHOME + 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 @@ -40,3 +45,10 @@ log_fatal () { /run/s6/basedir/bin/halt exit 1 } + +# param $1: group_name +get_group_id () { + if [ "${1:-}" != '' ]; then + getent group "$1" | cut -d: -f3 + fi +} diff --git a/docker/rootfs/etc/nginx/nginx.conf b/docker/rootfs/etc/nginx/nginx.conf index c2ee97cce..826183378 100644 --- a/docker/rootfs/etc/nginx/nginx.conf +++ b/docker/rootfs/etc/nginx/nginx.conf @@ -1,7 +1,7 @@ # run nginx in foreground daemon off; pid /run/nginx/nginx.pid; -user npmuser; +user npm; # Set number of worker processes automatically based on number of CPU cores. worker_processes auto; 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 9fe0831df..f3209de73 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -12,12 +12,12 @@ cd /app || exit 1 log_info 'Starting backend ...' if [ "${DEVELOPMENT:-}" = 'true' ]; then - 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' + s6-setuidgid "$PUID:$PGID" yarn install + exec s6-setuidgid "$PUID:$PGID" bash -c "export HOME=$NPMHOME;node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js" else while : do - s6-setuidgid npmuser bash -c 'export HOME=/tmp/npmuserhome;node --abort_on_uncaught_exception --max_old_space_size=250 index.js' + s6-setuidgid "$PUID:$PGID" bash -c "export HOME=$NPMHOME;node --abort_on_uncaught_exception --max_old_space_size=250 index.js" 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 1181c53e4..e62f749ce 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,14 @@ set -e if [ "$DEVELOPMENT" = 'true' ]; then . /bin/common.sh cd /app/frontend || exit 1 - HOME=/tmp/npmuserhome + HOME=$NPMHOME export HOME mkdir -p /app/frontend/dist chown -R "$PUID:$PGID" /app/frontend/dist log_info 'Starting frontend ...' - s6-setuidgid npmuser yarn install - exec s6-setuidgid npmuser yarn watch + s6-setuidgid "$PUID:$PGID" yarn install + exec s6-setuidgid "$PUID:$PGID" yarn watch 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 fa8c1fc50..b1bed7a44 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -6,4 +6,4 @@ set -e . /bin/common.sh log_info 'Starting nginx ...' -exec s6-setuidgid npmuser nginx +exec s6-setuidgid "$PUID:$PGID" nginx diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh index 1d5899e43..82fbefb1c 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh @@ -9,7 +9,11 @@ if [ "$(id -u)" != "0" ]; then log_fatal "This docker container must be run as root, do not specify a user.\nYou can specify PUID and PGID env vars to run processes as that user and group after initialization." fi -. /etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh +if [ "$DEBUG" = "true" ]; then + set -x +fi + +. /etc/s6-overlay/s6-rc.d/prepare/10-usergroup.sh . /etc/s6-overlay/s6-rc.d/prepare/20-paths.sh . /etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh . /etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh 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 deleted file mode 100755 index 1f290de1c..000000000 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/command/with-contenv bash -# shellcheck shell=bash - -set -e -# verbose -set -x - -log_info 'Configuring npmuser ...' - -if id -u npmuser; then - # user already exists - usermod -u "$PUID" npmuser || exit 1 -else - # Add npmuser user - useradd -o -u "$PUID" -U -d /tmp/npmuserhome -s /bin/false npmuser || exit 1 -fi - -usermod -G "$PGID" npmuser || exit 1 -groupmod -o -g "$PGID" npmuser || exit 1 -# Home for npmuser -mkdir -p /tmp/npmuserhome -chown -R "$PUID:$PGID" /tmp/npmuserhome diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-usergroup.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-usergroup.sh new file mode 100755 index 000000000..ea1001938 --- /dev/null +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-usergroup.sh @@ -0,0 +1,40 @@ +#!/command/with-contenv bash +# shellcheck shell=bash + +set -e + +log_info "Configuring $NPMUSER user ..." + +if id -u "$NPMUSER" 2>/dev/null; then + # user already exists + usermod -u "$PUID" "$NPMUSER" +else + # Add user + useradd -o -u "$PUID" -U -d "$NPMHOME" -s /bin/false "$NPMUSER" +fi + +log_info "Configuring $NPMGROUP group ..." +if [ "$(get_group_id "$NPMGROUP")" = '' ]; then + # Add group. This will not set the id properly if it's already taken + groupadd -f -g "$PGID" "$NPMGROUP" +else + groupmod -o -g "$PGID" "$NPMGROUP" +fi + +# Set the group ID and check it +groupmod -o -g "$PGID" "$NPMGROUP" +if [ "$(get_group_id "$NPMGROUP")" != "$PGID" ]; then + echo "ERROR: Unable to set group id properly" + exit 1 +fi + +# Set the group against the user and check it +usermod -G "$PGID" "$NPMGROUP" +if [ "$(id -g "$NPMUSER")" != "$PGID" ] ; then + echo "ERROR: Unable to set group against the user properly" + exit 1 +fi + +# Home for user +mkdir -p "$NPMHOME" +chown -R "$PUID:$PGID" "$NPMHOME" diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh index 12f6400e9..2f59ef41a 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh @@ -2,8 +2,6 @@ # shellcheck shell=bash set -e -# verbose -set -x log_info 'Checking paths ...' 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 3c583ab3b..817c2c8e3 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 @@ -2,15 +2,13 @@ # shellcheck shell=bash set -e -# verbose -set -x log_info 'Setting ownership ...' # root chown root /tmp/nginx -# npmuser +# npm user and group chown -R "$PUID:$PGID" /data chown -R "$PUID:$PGID" /etc/letsencrypt chown -R "$PUID:$PGID" /run/nginx diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh index d13fae7a8..0cb9f1264 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh @@ -2,8 +2,6 @@ # shellcheck shell=bash set -e -# verbose -set -x log_info 'Dynamic resolvers ...' diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh index 3e583bfa4..76e9a6510 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh @@ -5,8 +5,6 @@ # or disable ipv6 in all nginx configs based on this setting. set -e -# verbose -set -x log_info 'IPv6 ...' @@ -33,7 +31,7 @@ process_folder () { sed -E -i "$SED_REGEX" "$FILE" done - # ensure the files are still owned by the npmuser + # ensure the files are still owned by the npm user chown -R "$PUID:$PGID" "$1" } diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh index 1a7243820..faa22accb 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh @@ -2,8 +2,6 @@ # shellcheck shell=bash set -e -# verbose -set -x # in s6, environmental variables are written as text files for s6 to monitor # search through full-path filenames for files ending in "__FILE" 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 7991ddf4f..48ba63923 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 @@ -2,6 +2,7 @@ # shellcheck shell=bash set -e +set +x echo " ------------------------------------- @@ -11,7 +12,7 @@ echo " | |\ | __/| | | | |_| \_|_| |_| |_| ------------------------------------- -User ID: $PUID -Group ID: $PGID +User: $NPMUSER PUID:$PUID ID:$(id -u "$NPMUSER") GROUP:$(id -g "$NPMUSER") +Group: $NPMGROUP PGID:$PGID ID:$(get_group_id "$NPMGROUP") ------------------------------------- " From c3735fdbbb0e9ccc8f8a64c3a1ed76efb5472157 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Thu, 4 May 2023 12:30:27 +1000 Subject: [PATCH 022/334] Missed a file that was explicit verbose --- docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run | 2 -- 1 file changed, 2 deletions(-) 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 f3209de73..197461691 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/backend/run @@ -2,8 +2,6 @@ # shellcheck shell=bash set -e -# verbose -set -x . /bin/common.sh From 4f41fe0c953176dd0ce00b222389e85d5ca4d6c9 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Fri, 5 May 2023 08:46:54 +1000 Subject: [PATCH 023/334] Update s6-overlay --- docker/scripts/install-s6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/scripts/install-s6 b/docker/scripts/install-s6 index 5a5a9c9c3..8a236d51d 100755 --- a/docker/scripts/install-s6 +++ b/docker/scripts/install-s6 @@ -8,7 +8,7 @@ BLUE='\E[1;34m' GREEN='\E[1;32m' RESET='\E[0m' -S6_OVERLAY_VERSION=3.1.4.1 +S6_OVERLAY_VERSION=3.1.4.2 TARGETPLATFORM=${1:unspecified} # Determine the correct binary file for the architecture given From ecf02902032e4bde9bd67b4db7327ec93ca0c152 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 9 May 2023 08:15:44 +1000 Subject: [PATCH 024/334] Update s6-overlay --- docker/scripts/install-s6 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/scripts/install-s6 b/docker/scripts/install-s6 index 8a236d51d..0681aed94 100755 --- a/docker/scripts/install-s6 +++ b/docker/scripts/install-s6 @@ -8,7 +8,7 @@ BLUE='\E[1;34m' GREEN='\E[1;32m' RESET='\E[0m' -S6_OVERLAY_VERSION=3.1.4.2 +S6_OVERLAY_VERSION=3.1.5.0 TARGETPLATFORM=${1:unspecified} # Determine the correct binary file for the architecture given From c3f019c911f21a4fd446b377c7a7f4c45d092a60 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Tue, 9 May 2023 08:19:09 +1000 Subject: [PATCH 025/334] Test ipv6 disabled in ci --- docker/docker-compose.ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/docker-compose.ci.yml b/docker/docker-compose.ci.yml index 9f4edc00e..209d2d0e6 100644 --- a/docker/docker-compose.ci.yml +++ b/docker/docker-compose.ci.yml @@ -35,6 +35,7 @@ services: DB_SQLITE_FILE: '/data/mydb.sqlite' PUID: 1000 PGID: 1000 + DISABLE_IPV6: 'true' volumes: - npm_data:/data expose: From 4b6f9d9419b004a1f5734eea4b96231870623fa8 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 10 May 2023 09:57:24 +1000 Subject: [PATCH 026/334] Remove s6 service timeout --- docker/Dockerfile | 6 +++++- docker/dev/Dockerfile | 10 +++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 564f838af..b1cd31a26 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -10,9 +10,13 @@ ARG BUILD_VERSION ARG BUILD_COMMIT ARG BUILD_DATE +# See: https://github.com/just-containers/s6-overlay/blob/master/README.md ENV SUPPRESS_NO_CONFIG_WARNING=1 \ - S6_FIX_ATTRS_HIDDEN=1 \ S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_FIX_ATTRS_HIDDEN=1 \ + S6_KILL_FINISH_MAXTIME=10000 \ + S6_VERBOSITY=1 \ NODE_ENV=production \ NPM_BUILD_VERSION="${BUILD_VERSION}" \ NPM_BUILD_COMMIT="${BUILD_COMMIT}" \ diff --git a/docker/dev/Dockerfile b/docker/dev/Dockerfile index 833f10034..749ac343c 100644 --- a/docker/dev/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,9 +1,13 @@ FROM jc21/nginx-full:certbot-node LABEL maintainer="Jamie Curnow " -ENV S6_LOGGING=0 \ - SUPPRESS_NO_CONFIG_WARNING=1 \ - S6_FIX_ATTRS_HIDDEN=1 +# See: https://github.com/just-containers/s6-overlay/blob/master/README.md +ENV SUPPRESS_NO_CONFIG_WARNING=1 \ + S6_BEHAVIOUR_IF_STAGE2_FAILS=1 \ + S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ + S6_FIX_ATTRS_HIDDEN=1 \ + S6_KILL_FINISH_MAXTIME=10000 \ + S6_VERBOSITY=2 RUN echo "fs.file-max = 65535" > /etc/sysctl.conf \ && apt-get update \ From 0127dc7f03b98ce5d53d3c1b56ce36a564491aca Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 10 May 2023 11:32:22 +1000 Subject: [PATCH 027/334] Bump version --- .version | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.version b/.version index c6436a853..5f4f65c85 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.10.2 +2.10.3 diff --git a/README.md b/README.md index eefa11eb9..95d6551a9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@



- + From 05307aa253c073cf94237fc96d816ec2919f4d7f Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 10 May 2023 14:39:08 +1000 Subject: [PATCH 028/334] Fix certbot plugins install when using PUID/PGID --- backend/setup.js | 2 +- docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/setup.js b/backend/setup.js index a805978ba..403c14e72 100644 --- a/backend/setup.js +++ b/backend/setup.js @@ -131,7 +131,7 @@ const setupCertbotPlugins = () => { }); if (plugins.length) { - const install_cmd = '. /opt/certbot/bin/activate && pip install --no-cache-dir --user ' + plugins.join(' ') + ' && deactivate'; + const install_cmd = '. /opt/certbot/bin/activate && pip install --no-cache-dir ' + plugins.join(' ') + ' && deactivate'; promises.push(utils.exec(install_cmd)); } 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 817c2c8e3..a714298bb 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 @@ -22,3 +22,6 @@ chown -R "$PUID:$PGID" /var/log/nginx chown -R "$PUID:$PGID" /etc/nginx/nginx chown -R "$PUID:$PGID" /etc/nginx/nginx.conf chown -R "$PUID:$PGID" /etc/nginx/conf.d + +# Prevents errors when installing python certbot plugins when non-root +chown -R "$PUID:$PGID" /opt/certbot From 4c59400731b5bc432649d8a0f7aa2bffec79c634 Mon Sep 17 00:00:00 2001 From: Benjamin Hubert Date: Tue, 16 May 2023 21:46:26 +0200 Subject: [PATCH 029/334] added support for dns.he.net certbot plugin #2153 --- global/certbot-dns-plugins.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/global/certbot-dns-plugins.js b/global/certbot-dns-plugins.js index 8ac9ea817..042f674ca 100644 --- a/global/certbot-dns-plugins.js +++ b/global/certbot-dns-plugins.js @@ -286,6 +286,16 @@ dns_google_domains_zone = "example.com"`, full_plugin_name: 'dns-google-domains', }, //####################################################// + he: { + display_name: 'Hurricane Electric', + package_name: 'certbot-dns-he', + version_requirement: '~=1.0.0', + dependencies: '', + credentials: `dns_he_user = Me +dns_he_pass = my HE password`, + full_plugin_name: 'dns-he', + }, + //####################################################// hetzner: { display_name: 'Hetzner', package_name: 'certbot-dns-hetzner', From 847e879b3f3f8bce40ac00306603ea8d087a37b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Maa=C3=9F?= Date: Thu, 18 May 2023 13:44:52 +0200 Subject: [PATCH 030/334] Update certbot-dns-plugins.js Add dns wildcard certificate support for strato.de using the provided certbot plugin --- global/certbot-dns-plugins.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/global/certbot-dns-plugins.js b/global/certbot-dns-plugins.js index 8ac9ea817..0cda3fa3b 100644 --- a/global/certbot-dns-plugins.js +++ b/global/certbot-dns-plugins.js @@ -521,6 +521,19 @@ aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY`, full_plugin_name: 'dns-route53', }, //####################################################// + strato: { + display_name: 'Strato', + package_name: 'certbot-dns-strato', + version_requirement: '~=0.1.1', + dependencies: '', + credentials: `dns_strato_username = user +dns_strato_password = pass +# uncomment if domain name contains special characters +# insert domain display name as seen on your account page here +# dns_strato_domain_display_name = my-punicode-url.de`, + full_plugin_name: 'dns-strato', + }, + //####################################################// transip: { display_name: 'TransIP', package_name: 'certbot-dns-transip', From 53d61bd626bd5fb7cc787f7645a374824cf36eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Maa=C3=9F?= Date: Thu, 18 May 2023 14:14:38 +0200 Subject: [PATCH 031/334] Try to fix linter error in certbot plugin definitions. --- global/certbot-dns-plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global/certbot-dns-plugins.js b/global/certbot-dns-plugins.js index 0cda3fa3b..91555898d 100644 --- a/global/certbot-dns-plugins.js +++ b/global/certbot-dns-plugins.js @@ -531,7 +531,7 @@ dns_strato_password = pass # uncomment if domain name contains special characters # insert domain display name as seen on your account page here # dns_strato_domain_display_name = my-punicode-url.de`, - full_plugin_name: 'dns-strato', + full_plugin_name: 'dns-strato', }, //####################################################// transip: { From 81054631f9e42a4146e5f09fa1d98a72730f1167 Mon Sep 17 00:00:00 2001 From: nietzscheanic <101259812+nietzscheanic@users.noreply.github.com> Date: Fri, 19 May 2023 14:13:29 +0200 Subject: [PATCH 032/334] Fix for ignored ssl_protocols and ssl_ciphers directive in conf.d/include/ssl-ciphers.conf nginx only uses the `ssl_protocols` directive in the `server{}` block of the first processed host config, which is the default config in `/etc/nginx/conf.d/default.conf`. in version `v2.9.20` the default ssl site was dropped by using `ssl_reject_handshake on` in the default host config. but beside the include of `conf.d/include/ssl-ciphers.conf` was removed from the default host config. that's why `tlsv1.3` isn't applied by default anymore, same thing with the defined cipher suites. npm is so broken since `2023-03-16`. commit that broke the config -> https://github.com/NginxProxyManager/nginx-proxy-manager/commit/a7f0c3b730678ae4352ade2829d891a3ce3cd3bc --- docker/rootfs/etc/nginx/conf.d/default.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/rootfs/etc/nginx/conf.d/default.conf b/docker/rootfs/etc/nginx/conf.d/default.conf index 3368250ef..e4262e1dc 100644 --- a/docker/rootfs/etc/nginx/conf.d/default.conf +++ b/docker/rootfs/etc/nginx/conf.d/default.conf @@ -32,6 +32,7 @@ server { server_name localhost; access_log /data/logs/fallback_access.log standard; error_log /dev/null crit; + include conf.d/include/ssl-ciphers.conf; ssl_reject_handshake on; return 444; From 2dd4434ceb976d429e164f78d5941e08ffa2d802 Mon Sep 17 00:00:00 2001 From: Will Rouesnel Date: Mon, 22 May 2023 11:59:50 +1000 Subject: [PATCH 033/334] Add support for nginx 444 default response The default nginx 444 response drops the inbound connection without sending any response to the client. --- backend/templates/default.conf | 6 ++++++ frontend/js/app/settings/default-site/main.ejs | 4 ++++ frontend/js/i18n/messages.json | 1 + 3 files changed, 11 insertions(+) diff --git a/backend/templates/default.conf b/backend/templates/default.conf index ec68530ca..cc590f9d8 100644 --- a/backend/templates/default.conf +++ b/backend/templates/default.conf @@ -24,6 +24,12 @@ server { } {% endif %} +{%- if value == "444" %} + location / { + return 444; + } +{% endif %} + {%- if value == "redirect" %} location / { return 301 {{ meta.redirect }}; diff --git a/frontend/js/app/settings/default-site/main.ejs b/frontend/js/app/settings/default-site/main.ejs index 126c9d0ac..f1c4ccf62 100644 --- a/frontend/js/app/settings/default-site/main.ejs +++ b/frontend/js/app/settings/default-site/main.ejs @@ -18,6 +18,10 @@ >

<%- i18n('settings', 'default-site-404') %>
+