From db4ab1d548ab2d0b0bbe620034a9a48563ebd642 Mon Sep 17 00:00:00 2001 From: Jamie Curnow Date: Wed, 3 May 2023 16:01:27 +1000 Subject: [PATCH 01/11] 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 e8ffa17..9fe0831 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 c5cf543..1f290de 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 2f59ef4..12f6400 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 684166e..41da358 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 0cb9f12..d13fae7 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 bc27eb1..3e583bf 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 faa22ac..1a72438 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 02/11] 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 41da358..3c583ab 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 03/11] 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 0bc6468..913dd3e 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 c2ee97c..8261833 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 9fe0831..f3209de 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 1181c53..e62f749 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 fa8c1fc..b1bed7a 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 1d5899e..82fbefb 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 1f290de..0000000 --- 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 0000000..ea10019 --- /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 12f6400..2f59ef4 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 3c583ab..817c2c8 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 d13fae7..0cb9f12 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 3e583bf..76e9a65 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 1a72438..faa22ac 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 7991ddf..48ba639 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 04/11] 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 f3209de..1974616 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 05/11] 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 5a5a9c9..8a236d5 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 06/11] 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 8a236d5..0681aed 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 07/11] 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 9f4edc0..209d2d0 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 08/11] 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 564f838..b1cd31a 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 833f100..749ac34 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 09/11] Bump version --- .version | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.version b/.version index c6436a8..5f4f65c 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.10.2 +2.10.3 diff --git a/README.md b/README.md index eefa11e..95d6551 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 10/11] 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 a805978..403c14e 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 817c2c8..a714298 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 cd3ca9b3ad96961c9e81a54c8776999b217b4bc7 Mon Sep 17 00:00:00 2001 From: chishin Date: Sat, 28 Oct 2023 11:27:27 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E5=9F=BA=E4=BA=8Ev2.10.3=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=B8=AD=E6=96=87=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker.yml | 45 ++++ README-en.md | 111 ++++++++++ README.md | 156 ++++++++------ docker/Dockerfile-zh | 22 ++ docker/rootfs/var/www/html/index.html | 12 +- frontend/html/index.ejs | 2 +- frontend/html/login.ejs | 2 +- frontend/html/partials/header.ejs | 6 +- frontend/js/app/cache.js | 2 +- frontend/js/app/i18n.js | 6 +- frontend/js/app/nginx/access/form.ejs | 8 +- frontend/js/app/ui/footer/main.ejs | 3 +- frontend/js/i18n/messages.json | 293 ++++++++++++++++++++++++++ frontend/package.json | 2 +- scripts/build-zh | 8 + scripts/buildx-zh | 20 ++ 16 files changed, 610 insertions(+), 88 deletions(-) create mode 100644 .github/workflows/docker.yml create mode 100644 README-en.md create mode 100644 docker/Dockerfile-zh create mode 100644 scripts/build-zh create mode 100644 scripts/buildx-zh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..cc5da1d --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,45 @@ +name: GitHub Actions Docker Buildx +on: + workflow_dispatch: + push: + branches: + - 'develop-zh' + release: + types: [published] +jobs: + Docker-Buildx: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: 添加Build环境变量 + run: | + echo "BUILD_IMAGE=chishin/nginx-proxy-manager-zh" >> $GITHUB_ENV + echo "BUILD_PLATFORM=linux/amd64,linux/arm64,linux/arm/7" >> $GITHUB_ENV + echo "BUILD_VERSION=$(cat .version)" >> $GITHUB_ENV + - name: 添加BuildTag环境变量(push) + if: ${{ github.event_name == 'push'}} + run: | + echo "BUILD_TAG=-t ${BUILD_IMAGE}:${BUILD_VERSION} -t ${BUILD_IMAGE}:dev" >> $GITHUB_ENV + - name: 添加BuildTag环境变量(release) + if: ${{ github.event_name == 'release'}} + run: | + echo "BUILD_TAG=-t ${BUILD_IMAGE}:${BUILD_VERSION} -t ${BUILD_IMAGE}:${BUILD_VERSION%.*} -t ${BUILD_IMAGE}:${BUILD_VERSION%.*.*} -t ${BUILD_IMAGE}:release" >> $GITHUB_ENV + - name: 登录DockerHub账号 + env: + DOCKER_USERNAME: ${{secrets.DOCKER_USERNAME}} + DOCKER_PASSWORD: ${{secrets.DOCKER_PASSWORD}} + run: echo "${DOCKER_PASSWORD}" | docker login --username ${DOCKER_USERNAME} --password-stdin + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v2.5.0 + - name: 输出Buildx环境变量 + run: | + echo "BUILD_TAG=$BUILD_TAG" + echo "BUILD_IMAGE=$BUILD_IMAGE" + echo "BUILD_PLATFORM=$BUILD_PLATFORM" + echo "BUILD_VERSION=$BUILD_VERSION" + - name: Buildx Dockerfile + run: | + chmod -R 755 scripts + ./scripts/buildx-zh + diff --git a/README-en.md b/README-en.md new file mode 100644 index 0000000..95d6551 --- /dev/null +++ b/README-en.md @@ -0,0 +1,111 @@ +

+ +

+ + + + + + + +

+ +This project comes as a pre-built docker image that enables you to easily forward to your websites +running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt. + +- [Quick Setup](#quick-setup) +- [Full Setup](https://nginxproxymanager.com/setup/) +- [Screenshots](https://nginxproxymanager.com/screenshots/) + +## Project Goal + +I created this project to fill a personal need to provide users with a easy way to accomplish reverse +proxying hosts with SSL termination and it had to be so easy that a monkey could do it. This goal hasn't changed. +While there might be advanced options they are optional and the project should be as simple as possible +so that the barrier for entry here is low. + +Buy Me A Coffee + + +## Features + +- Beautiful and Secure Admin Interface based on [Tabler](https://tabler.github.io/) +- Easily create forwarding domains, redirections, streams and 404 hosts without knowing anything about Nginx +- Free SSL using Let's Encrypt or provide your own custom SSL certificates +- Access Lists and basic HTTP Authentication for your hosts +- Advanced Nginx configuration available for super users +- User management, permissions and audit log + + +## Hosting your home network + +I won't go in to too much detail here but here are the basics for someone new to this self-hosted world. + +1. Your home router will have a Port Forwarding section somewhere. Log in and find it +2. Add port forwarding for port 80 and 443 to the server hosting this project +3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns) +4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services + +## Quick Setup + +1. Install Docker and Docker-Compose + +- [Docker Install documentation](https://docs.docker.com/install/) +- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/) + +2. Create a docker-compose.yml file similar to this: + +```yml +version: '3.8' +services: + app: + image: 'jc21/nginx-proxy-manager:latest' + restart: unless-stopped + ports: + - '80:80' + - '81:81' + - '443:443' + volumes: + - ./data:/data + - ./letsencrypt:/etc/letsencrypt +``` + +This is the bare minimum configuration required. See the [documentation](https://nginxproxymanager.com/setup/) for more. + +3. Bring up your stack by running + +```bash +docker-compose up -d + +# If using docker-compose-plugin +docker compose up -d + +``` + +4. Log in to the Admin UI + +When your docker container is running, connect to it on port `81` for the admin interface. +Sometimes this can take a little bit because of the entropy of keys. + +[http://127.0.0.1:81](http://127.0.0.1:81) + +Default Admin User: +``` +Email: admin@example.com +Password: changeme +``` + +Immediately after logging in with this default user you will be asked to modify your details and change your password. + + +## Contributors + +Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors). + + +## Getting Support + +1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues) +2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions) +3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community) +4. [Reddit](https://reddit.com/r/nginxproxymanager) diff --git a/README.md b/README.md index 95d6551..6b875d5 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,35 @@ + +[Original English README](https://github.com/xiaoxinpro/nginx-proxy-manager-zh/blob/develop-zh/README-en.md) +

- -

- - - - - - - + +

-This project comes as a pre-built docker image that enables you to easily forward to your websites -running at home or otherwise, including free SSL, without having to know too much about Nginx or Letsencrypt. +本项目是基于 [NginxProxyManager/nginx-proxy-manager](https://github.com/NginxProxyManager/nginx-proxy-manager) 翻译的中文版本,该项目属于一个预构建的docker映像,它可以让你轻松地部署到你的网站上运行,包括免费的SSL,而不需要知道太多关于 Nginx 或 Let's Encrypt 的信息。 -- [Quick Setup](#quick-setup) -- [Full Setup](https://nginxproxymanager.com/setup/) -- [Screenshots](https://nginxproxymanager.com/screenshots/) +![](http://image.xiaoxin.pro/2022/05/16/75687b5bfffbe.png) -## Project Goal +## 快速部署 -I created this project to fill a personal need to provide users with a easy way to accomplish reverse -proxying hosts with SSL termination and it had to be so easy that a monkey could do it. This goal hasn't changed. -While there might be advanced options they are optional and the project should be as simple as possible -so that the barrier for entry here is low. +### 1. 环境部署 -Buy Me A Coffee +安装Docker和Docker-compose +- [Docker官方安装文档(英文)](https://docs.docker.com/install/) +- [Docker-Compose官方安装文档(英文)](https://docs.docker.com/compose/install/) +- **[Docker和Docker-compose安装文档(中文)](https://blog.csdn.net/zhangzejin3883/article/details/124778945)** -## Features +### 2. 创建YAML文件 -- Beautiful and Secure Admin Interface based on [Tabler](https://tabler.github.io/) -- Easily create forwarding domains, redirections, streams and 404 hosts without knowing anything about Nginx -- Free SSL using Let's Encrypt or provide your own custom SSL certificates -- Access Lists and basic HTTP Authentication for your hosts -- Advanced Nginx configuration available for super users -- User management, permissions and audit log - - -## Hosting your home network - -I won't go in to too much detail here but here are the basics for someone new to this self-hosted world. - -1. Your home router will have a Port Forwarding section somewhere. Log in and find it -2. Add port forwarding for port 80 and 443 to the server hosting this project -3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns) -4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services - -## Quick Setup - -1. Install Docker and Docker-Compose - -- [Docker Install documentation](https://docs.docker.com/install/) -- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/) - -2. Create a docker-compose.yml file similar to this: +创建一个 `docker-compose.yml` 文件: ```yml -version: '3.8' +version: '3' services: app: - image: 'jc21/nginx-proxy-manager:latest' - restart: unless-stopped + image: 'chishin/nginx-proxy-manager-zh:release' + restart: always ports: - '80:80' - '81:81' @@ -70,42 +39,93 @@ services: - ./letsencrypt:/etc/letsencrypt ``` -This is the bare minimum configuration required. See the [documentation](https://nginxproxymanager.com/setup/) for more. - -3. Bring up your stack by running +### 3. 部署运行 ```bash docker-compose up -d - -# If using docker-compose-plugin -docker compose up -d - ``` -4. Log in to the Admin UI +### 4. 登录管理页面 -When your docker container is running, connect to it on port `81` for the admin interface. -Sometimes this can take a little bit because of the entropy of keys. +当你的docker容器成功运行,使用浏览器访问`81`端口。 +有些时候需要稍等一段时间。 [http://127.0.0.1:81](http://127.0.0.1:81) -Default Admin User: +默认管理员信息: ``` Email: admin@example.com Password: changeme ``` -Immediately after logging in with this default user you will be asked to modify your details and change your password. +使用这个默认用户登录后,系统会立即要求您修改详细信息和密码。 +### 5. 快速升级 -## Contributors +```bash +docker-compose down +docker-compose pull +docker-compose up -d +``` -Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors). +这个项目将自动更新任何数据库或其他要求,所以你不必遵循任何疯狂的指示。上面的这些步骤将提取最新的更新并重新创建docker容器。 +## 更多 -## Getting Support +### 1. 官方文档(英文) -1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues) -2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions) -3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community) -4. [Reddit](https://reddit.com/r/nginxproxymanager) +关于本应用的更多用法请访问官方文档: + +- [项目源码](https://github.com/NginxProxyManager/nginx-proxy-manager) +- [项目官网](https://nginxproxymanager.com/) +- [安装手册](https://nginxproxymanager.com/setup/) +- [高级配置](https://nginxproxymanager.com/advanced-config/#best-practice-use-a-docker-network) +- [常见问题](https://nginxproxymanager.com/faq/#do-i-have-to-use-docker) + +### 2. 替换中文镜像 + +当你使用官方示例的`docker-compose`时需要注意,将image镜像`jc21/nginx-proxy-manager`替换为`chishin/nginx-proxy-manager-zh`即可实现中文部署。 + +### 3. 关于中文镜像 + +中文镜像并没有重新构建后端代码,由[Dockerfile-zh](https://github.com/xiaoxinpro/nginx-proxy-manager-zh/blob/develop-zh/docker/Dockerfile-zh)文件可以得知,中文镜像基于官方镜像替换前端代码来实现的,所以中文版本的全部功能与官方版本完全相同,只是显示界面的文字不同的区别。 + +### 4. 关于DNSPod创建证书失败 + +此问题在2.9.19版本开始就已经存在,原因是`zope`引起的,由于ARM架构一直安装失败所以无法打包到镜像中,建议使用如下方法修复此问题: + +首先确保nginx-proxy-manager-zh的Docker容器已经正常运行,使用`docker-compose ps`查看容器名,这里假设容器名为`npm-zh`。 + +进入容器:(注意替换下文中的容器名) + +``` +docker exec -it npm-zh bash +``` + +执行安装`zope`命令: + +``` +python3 -m pip install --upgrade pip +pip install certbot-dns-dnspod +pip install zope +``` + +等待安装完成,退出容器: + +``` +exit +``` + +最后刷新浏览器,再次使用DNSPod创建证书即可。 + +## 捐赠 + +如果您觉得本项目对你有帮助,欢迎给予我们一定的捐助来翻译项目的长期发展。 + +### 支付宝扫码捐赠 + +![支付宝扫码捐赠](https://image.xiaoxin.pro/2022/05/16/1f1a5f025c13c.png) + +### 微信扫描捐赠 + +![微信扫描捐赠](https://image.xiaoxin.pro/2022/05/16/9c9906b102b29.png) diff --git a/docker/Dockerfile-zh b/docker/Dockerfile-zh new file mode 100644 index 0000000..be62643 --- /dev/null +++ b/docker/Dockerfile-zh @@ -0,0 +1,22 @@ +FROM jc21/nginx-proxy-manager:2.10.3 + +ENV NPM_LANGUAGE="zh" + +EXPOSE 80 81 443 + +RUN rm -rf /app/frontend /var/www/html/index.html +COPY frontend/dist /app/frontend +COPY docker/rootfs/var/www/html/index.html /var/www/html/index.html + +WORKDIR /app + +VOLUME [ "/data", "/etc/letsencrypt" ] +ENTRYPOINT [ "/init" ] + +LABEL org.label-schema.schema-version="1.0" \ + org.label-schema.license="MIT" \ + org.label-schema.name="nginx-proxy-manager-zh" \ + org.label-schema.description="Docker container for managing Nginx proxy hosts with a simple, powerful interface " \ + org.label-schema.url="https://github.com/xiaoxinpro/nginx-proxy-manager-zh" \ + org.label-schema.vcs-url="https://github.com/xiaoxinpro/nginx-proxy-manager-zh.git" \ + org.label-schema.cmd="docker run --rm -ti chishin/nginx-proxy-manager-zh:latest" diff --git a/docker/rootfs/var/www/html/index.html b/docker/rootfs/var/www/html/index.html index 8478b47..88289da 100644 --- a/docker/rootfs/var/www/html/index.html +++ b/docker/rootfs/var/www/html/index.html @@ -1,5 +1,5 @@ - + @@ -13,12 +13,12 @@
-

Congratulations!

-

You've successfully started the Nginx Proxy Manager.

-

If you're seeing this site then you're trying to access a host that isn't set up yet.

-

Log in to the Admin panel to get started.

+

恭喜!

+

您已成功启动 Nginx 代理管理器。

+

如果您看到此站点,则说明您正在尝试访问尚未设置的主机。

+

登录管理面板开始使用。

-

Powered by Nginx Proxy Manager

+

Powered by Nginx Proxy Manager

diff --git a/frontend/html/index.ejs b/frontend/html/index.ejs index ae08b01..838d138 100644 --- a/frontend/html/index.ejs +++ b/frontend/html/index.ejs @@ -1,4 +1,4 @@ -<% var title = 'Nginx Proxy Manager' %> +<% var title = 'Nginx 代理管理器' %> <%- include partials/header.ejs %>
diff --git a/frontend/html/login.ejs b/frontend/html/login.ejs index bc4b9a2..a217733 100644 --- a/frontend/html/login.ejs +++ b/frontend/html/login.ejs @@ -1,4 +1,4 @@ -<% var title = 'Login – Nginx Proxy Manager' %> +<% var title = '登录 – Nginx 代理管理器' %> <%- include partials/header.ejs %>
diff --git a/frontend/html/partials/header.ejs b/frontend/html/partials/header.ejs index b8d8833..6162493 100644 --- a/frontend/html/partials/header.ejs +++ b/frontend/html/partials/header.ejs @@ -1,10 +1,10 @@ - + - + @@ -27,7 +27,7 @@ diff --git a/frontend/js/app/cache.js b/frontend/js/app/cache.js index 6d1fbc4..723c721 100644 --- a/frontend/js/app/cache.js +++ b/frontend/js/app/cache.js @@ -2,7 +2,7 @@ const UserModel = require('../models/user'); let cache = { User: new UserModel.Model(), - locale: 'en', + locale: 'zh', version: null }; diff --git a/frontend/js/app/i18n.js b/frontend/js/app/i18n.js index c63cdc0..bf214f9 100644 --- a/frontend/js/app/i18n.js +++ b/frontend/js/app/i18n.js @@ -10,13 +10,13 @@ module.exports = function (namespace, key, data) { let locale = Cache.locale; // check that the locale exists if (typeof messages[locale] === 'undefined') { - locale = 'en'; + locale = 'zh'; } if (typeof messages[locale][namespace] !== 'undefined' && typeof messages[locale][namespace][key] !== 'undefined') { return messages[locale][namespace][key](data); - } else if (locale !== 'en' && typeof messages['en'][namespace] !== 'undefined' && typeof messages['en'][namespace][key] !== 'undefined') { - return messages['en'][namespace][key](data); + } else if (locale !== 'zh' && typeof messages['zh'][namespace] !== 'undefined' && typeof messages['zh'][namespace][key] !== 'undefined') { + return messages['zh'][namespace][key](data); } return '(MISSING: ' + namespace + '/' + key + ')'; diff --git a/frontend/js/app/nginx/access/form.ejs b/frontend/js/app/nginx/access/form.ejs index 79220b1..15f56bc 100644 --- a/frontend/js/app/nginx/access/form.ejs +++ b/frontend/js/app/nginx/access/form.ejs @@ -47,10 +47,11 @@

- Basic Authorization via + 授权用户基于 Nginx HTTP Basic Authentication + 实现

@@ -74,10 +75,11 @@

- IP Address Whitelist/Blacklist via + IP地址黑白名单基于 Nginx HTTP Access + 实现

@@ -92,7 +94,7 @@
-
Note that the allow and deny directives will be applied in the order they are defined.
+
注意: allow(允许)deny(禁止) 规则将按照它们定义的顺序执行。
diff --git a/frontend/js/app/ui/footer/main.ejs b/frontend/js/app/ui/footer/main.ejs index 99c2630..43555bd 100644 --- a/frontend/js/app/ui/footer/main.ejs +++ b/frontend/js/app/ui/footer/main.ejs @@ -3,7 +3,7 @@ @@ -12,5 +12,6 @@ <%- i18n('main', 'version', {version: getVersion()}) %> <%= i18n('footer', 'copy', {url: 'https://jc21.com?utm_source=nginx-proxy-manager'}) %> <%= i18n('footer', 'theme', {url: 'https://tabler.github.io/?utm_source=nginx-proxy-manager'}) %> + <%= i18n('footer', 'translate', {url: 'https://github.com/xiaoxinpro/nginx-proxy-manager-zh'}) %>
diff --git a/frontend/js/i18n/messages.json b/frontend/js/i18n/messages.json index aa544c7..a425966 100644 --- a/frontend/js/i18n/messages.json +++ b/frontend/js/i18n/messages.json @@ -290,5 +290,298 @@ "default-site-html": "Custom Page", "default-site-redirect": "Redirect" } + }, + "zh": { + "str": { + "email-address": "邮箱", + "username": "账号", + "password": "密码", + "sign-in": "登录", + "sign-out": "退出", + "try-again": "重试", + "name": "名字", + "email": "邮箱", + "roles": "角色", + "created-on": "创建:{date}", + "save": "保存", + "cancel": "取消", + "close": "关闭", + "enable": "启用", + "disable": "禁用", + "sure": "是的,我确定", + "disabled": "禁用", + "choose-file": "选择文件", + "source": "来源", + "destination": "目标地址", + "ssl": "SSL", + "access": "规则", + "public": "公开", + "edit": "编辑", + "delete": "删除", + "logs": "日志", + "status": "状态", + "online": "在线", + "offline": "离线", + "unknown": "未知", + "expires": "过期", + "value": "值", + "please-wait": "请稍等...", + "all": "全部", + "any": "任意" + }, + "login": { + "title": "登录到您的账户" + }, + "main": { + "app": "Nginx 代理管理器", + "version": "v{version}", + "welcome": "欢迎来到 Nginx 代理管理器", + "logged-in": "您的登录身份是 {name}", + "unknown-error": "加载出错,请重新加载应用程序。", + "unknown-user": "未知用户", + "sign-in-as": "重新登录为 {name}" + }, + "roles": { + "title": "角色", + "admin": "管理员", + "user": "Apache Helicopter" + }, + "menu": { + "dashboard": "仪表盘", + "hosts": "主机" + }, + "footer": { + "fork-me": "在Github上Fork项目", + "copy": "© 2022-2023 jc21.com, ", + "theme": "Theme by Tabler, ", + "translate": "汉化版由 xiaoxinpro 提供. " + }, + "dashboard": { + "title": "你好 {name}" + }, + "all-hosts": { + "empty-subtitle": "{manage, select, true{您为什么不创建一个?} other{您目前没有权限创建。}}", + "details": "详细内容", + "enable-ssl": "启用SSL", + "force-ssl": "强制SSL", + "http2-support": "支持HTTP/2", + "domain-names": "域名", + "cert-provider": "证书提供商", + "block-exploits": "阻止常见漏洞", + "caching-enabled": "缓存资源", + "ssl-certificate": "SSL证书", + "none": "无", + "new-cert": "申请一个新的SSL证书", + "with-le": "使用Let's Encrypt", + "no-ssl": "该主机将不使用HTTPS", + "advanced": "高级", + "advanced-warning": "在此输入你的自定义 Nginx 配置,风险自负!", + "advanced-config": "自定义 Nginx 配置", + "advanced-config-var-headline": "这些代理详情可以作为nginx的变量。", + "advanced-config-header-info": "请注意,这里添加的任何add_header或set_header配置都不会被nginx使用。你将不得不添加一个自定义的位置'/',并在那里的自定义配置中添加头信息。", + "hsts-enabled": "启用了HSTS", + "hsts-subdomains": "HSTS子域", + "locations": "自定义位置" + }, + "locations": { + "new_location": "添加位置", + "path": "/path", + "location_label": "定义位置", + "delete": "删除" + }, + "ssl": { + "letsencrypt": "Let's Encrypt", + "other": "上传证书", + "none": "仅HTTP", + "letsencrypt-email": "Let's Encrypt ", + "letsencrypt-agree": "我同意 Let's Encrypt 服务条款", + "delete-ssl": "附加的SSL证书将不会被删除,它们需要手动删除。", + "hosts-warning": "这些域名必须配置为指向本设备。", + "no-wildcard-without-dns": "不使用DNS认证时,不能用通配符域名申请Let's Encrypt证书", + "dns-challenge": "使用DNS认证", + "certbot-warning": "本节需要一些关于Certbot及其DNS扩展的知识。请查阅相关扩展的文档。", + "dns-provider": "DNS提供者", + "please-choose": "选择...", + "credentials-file-content": "证书内容", + "credentials-file-content-info": "这个插件需要一个包含API令牌或其他供应商凭证的配置文件。", + "stored-as-plaintext-info": "这些数据将以明文形式存储在数据库和文件中", + "propagation-seconds": "等待时间(秒)", + "propagation-seconds-info": "留空为默认值。等待DNS生效的时间(秒)。", + "processing-info": "处理中... 这可能需要几分钟的时间。", + "passphrase-protection-support-info": "不支持使用密码保护密钥文件。" + }, + "proxy-hosts": { + "title": "代理服务", + "empty": "目前还没有代理服务", + "add": "添加代理服务", + "form-title": "{id, select, undefined{新建} other{编辑}} 代理服务", + "forward-scheme": "协议", + "forward-host": "转发主机/IP", + "forward-port": "转发端口", + "delete": "删除代理服务", + "delete-confirm": "你确定要删除代理服务 {domains} 吗?", + "help-title": "什么是代理服务?", + "help-content": "代理服务是你想转发网络应用的主机。\n代理服务可以为没有SSL服务的网络应用提供SSL服务(可选)。\n代理服务是Nginx代理管理器的最常见用途之一。", + "access-list": "通信规则", + "allow-websocket-upgrade": "支持WebSockets", + "ignore-invalid-upstream-ssl": "忽略无效的SSL", + "custom-forward-host-help": "为子目录转发添加路径。\n例如:203.0.113.25/路径/", + "search": "搜索主机…" + }, + "redirection-hosts": { + "title": "重定向", + "empty": "目前还没有重定向", + "add": "添加重定向", + "form-title": "{id, select, undefined{新建} other{编辑}} 重定向", + "forward-scheme": "协议", + "forward-http-status-code": "HTTP 代码", + "forward-domain": "转发域名", + "preserve-path": "保留路径", + "delete": "删除重定向", + "delete-confirm": "确定要删除 {domains} 的重定向吗?", + "help-title": "什么是重定向?", + "help-content": "重定向是将接入域名的请求推送到另一个域名。\n使用这种类型的主机最常见的原因是当你的网站改变了域名,但你仍然有链接指向旧域名的应用。", + "search": "搜索主机…" + }, + "dead-hosts": { + "title": "错误页面", + "empty": "目前还没有错误页面", + "add": "添加错误页面", + "form-title": "{id, select, undefined{新建} other{编辑}} 错误页面", + "delete": "删除错误页面", + "delete-confirm": "确定要删除错误页面吗?", + "help-title": "什么是错误页面?", + "help-content": "错误页面是一个简单的主机设置,显示错误页面。\n当你的域名被列入搜索引擎,而你想提供一个更好的错误页面或特别是告诉搜索索引者域名页面不再存在时,这可能是有用的。\n拥有这种主机的另一个好处是可以跟踪点击它的日志并查看访问来源。", + "search": "搜索主机…" + }, + "streams": { + "title": "端口转发", + "empty": "目前还没有端口转发", + "add": "添加端口转发", + "form-title": "{id, select, undefined{新建} other{编辑}} 端口转发", + "incoming-port": "入站端口", + "forwarding-host": "转发主机", + "forwarding-port": "转发端口", + "tcp-forwarding": "TCP转发", + "udp-forwarding": "UDP转发", + "forward-type-error": "至少有一种协议必须被启用", + "protocol": "协议", + "tcp": "TCP", + "udp": "UDP", + "delete": "删除端口转发", + "delete-confirm": "你确定删除这个端口转发吗?", + "help-title": "什么是端口转发?", + "help-content": "端口转发是Nginx的一个相对较新的功能,可以直接转发TCP/UDP流量到网络上的另一台计算机。\n如果你正在运行游戏服务器、FTP或SSH服务器,这个功能就会很有用。", + "search": "搜索入站端口…" + }, + "certificates": { + "title": "SSL证书", + "empty": "目前还没有SSL证书", + "add": "添加SSL证书", + "form-title": "添加 {provider, select, letsencrypt{Let's Encrypt} other{上传}} 证书", + "delete": "删除SSL证书", + "delete-confirm": "你确定要删除这个SSL证书吗?任何使用该证书的主机之后都需要进行更新。", + "help-title": "SSL证书", + "help-content": "SSL证书(TLS证书)是一种加密密钥的形式,它允许你的网站为终端用户进行数据加密。\n目前使用Let's Encrypt的服务来免费发放SSL证书。\n如果你的代理服务后面有个人信息、密码或敏感数据,使用证书是个非常好的安全措施。\n如果你的网站不是面向互联网运行,或者你只是想要一个通配符证书,需要使用DNS认证获取证书。", + "other-certificate": "证书", + "other-certificate-key": "证书密钥", + "other-intermediate-certificate": "中间证书", + "force-renew": "现在更新", + "test-reachability": "测试服务器的可用性", + "reachability-title": "测试服务器的可用性", + "reachability-info": "使用 Site24x7 测试域名是否可以从公共互联网访问。在使用DNS认证时,没有必要这样做。", + "reachability-failed-to-reach-api": "与API的通信失败,请检查NPM是否正确运行?", + "reachability-failed-to-check": "由于与 site24x7.com 的通信错误,检查可用性失败。", + "reachability-ok": "您的服务器是可用的,创建证书应该是可能的。", + "reachability-404": "在这个域名中发现了一个服务器,但它似乎指向的不是本Nginx代理管理器。请确保你的域名指向本NPM实例的IP。", + "reachability-not-resolved": "在这个域名中没有可用的服务器。请确保你的域名存在,并且指向本NPM实例运行的IP,如果有必要,请检查80端口在路由器中是否被映射到外网。", + "reachability-wrong-data": "在这个域名中发现了一个服务器,但它返回了一个意外的数据。它是指向本NPM服务器吗?请确保你的域名指向本NPM实例的IP。", + "reachability-other": "在这个域名中发现了一个服务器,但它返回了一个意外的状态代码{code}。它是指向本NPM服务器吗?请确保你的域名指向本NPM实例的IP。", + "download": "下载", + "renew-title": "更新Let's Encrypt证书", + "search": "搜索证书…" + }, + "access-lists": { + "title": "通信规则", + "empty": "目前还没有通信规则", + "add": "添加通信规则", + "form-title": "{id, select, undefined{新建} other{编辑}} 通信规则", + "delete": "删除通信规则", + "delete-confirm": "您确定要删除这个通信规则吗?", + "public": "公开规则", + "public-sub": "没有规则限制", + "help-title": "什么是通信规则?", + "help-content": "通信规则提供了一个特定客户IP地址的黑名单或白名单,以及通过基本HTTP认证对代理服务的认证。\n你可以为一个通信规则配置多个客户规则、用户名和密码,然后将其应用于代理服务。\n这对那些没有内置认证机制的转发网络服务或你想保护其免受未知客户的访问是最有用的。", + "item-count": "{count} {count, select, 1{个} other{个}}", + "client-count": "{count} {count, select, 1{条} other{条}}", + "proxy-host-count": "{count} {count, select, 1{个} other{个}}", + "delete-has-hosts": "该通信规则与{count}代理服务有关,在被删除后将成为公开的。", + "details": "详情", + "authorization": "授权用户", + "access": "规则", + "satisfy": "满足", + "satisfy-any": "满足任何要求", + "pass-auth": "授权访问主机", + "access-add": "添加", + "auth-add": "添加", + "search": "搜索通信规则…" + }, + "users": { + "title": "用户", + "default_error": "必须改变默认的邮箱地址", + "add": "添加用户", + "nickname": "昵称", + "full-name": "名称", + "edit-details": "编辑详情", + "change-password": "修改密码", + "edit-permissions": "编辑权限", + "sign-in-as": "以此用户登录", + "form-title": "{id, select, undefined{新建} other{编辑}} 用户", + "delete": "删除 {name, select, undefined{User} other{{name}}}", + "delete-confirm": "您确定要删除 {name} 吗?", + "password-title": "修改密码{self, select, false{ {name}} other{}}", + "current-password": "修改密码", + "new-password": "新密码", + "confirm-password": "确认密码", + "permissions-title": "{name} 的权限", + "admin-perms": "该用户是管理员,一些项目不能被修改。", + "perms-visibility": "项目可见性", + "perms-visibility-user": "仅限创建的项目", + "perms-visibility-all": "所有项目", + "perm-manage": "管理项目", + "perm-view": "仅限查看", + "perm-hidden": "隐藏", + "search": "搜索用户…" + }, + "audit-log": { + "title": "检查日志", + "empty": "目前还没有日志。", + "empty-subtitle": "只要你或其他用户修改了什么,这些历史就会在这里显示出来。", + "proxy-host": "代理服务", + "redirection-host": "重定向", + "dead-host": "错误页面", + "stream": "端口转发", + "user": "用户", + "certificate": "证书", + "access-list": "通信规则", + "created": "创建 {name}", + "updated": "更新 {name}", + "deleted": "删除 {name}", + "enabled": "启用 {name}", + "disabled": "禁用 {name}", + "renewed": "续约 {name}", + "meta-title": "事件详情", + "view-meta": "查看详情", + "date": "日期", + "search": "搜索日志…" + }, + "settings": { + "title": "设置", + "default-site": "默认站点", + "default-site-congratulations": "成功页面", + "default-site-404": "错误页面", + "default-site-html": "自定义页面", + "default-site-redirect": "重定向" + } } } diff --git a/frontend/package.json b/frontend/package.json index 4965d0d..9e7b2d2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "nginx-proxy-manager", - "version": "0.0.0", + "version": "2.10.3", "description": "A beautiful interface for creating Nginx endpoints", "main": "js/index.js", "devDependencies": { diff --git a/scripts/build-zh b/scripts/build-zh new file mode 100644 index 0000000..3e859f5 --- /dev/null +++ b/scripts/build-zh @@ -0,0 +1,8 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$DIR/ci/frontend-build" + +cd "${DIR}/../.." + +docker build -t chishin/nginx-proxy-manager-zh:2.10.3 -f docker/Dockerfile-zh . diff --git a/scripts/buildx-zh b/scripts/buildx-zh new file mode 100644 index 0000000..6a14467 --- /dev/null +++ b/scripts/buildx-zh @@ -0,0 +1,20 @@ +#!/bin/bash + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +. "$DIR/ci/frontend-build" + +cd "${DIR}/../.." + +# Buildx Builder +docker buildx create --name "Buildx-NPM" || echo +docker buildx use "Buildx-NPM" + +if [ "${BUILD_TAG:-0}" != 0 ]; then + docker buildx build -f docker/Dockerfile-zh $BUILD_TAG --platform $BUILD_PLATFORM . --push +else + docker buildx build -f docker/Dockerfile-zh -t "chishin/nginx-proxy-manager-zh:dev" --platform linux/amd64,linux/arm64,linux/arm/7 . --push +fi + +docker buildx rm "Buildx-NPM" + +echo "Multiarch build Complete" \ No newline at end of file