mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Adds support to run processes as a user/group, defined
with PUID and PGID environment variables - Detects if image is run with a user in docker command and fails if so - Adds s6 prepare scripts for adding a 'npmuser' - Split up and refactor the s6 prepare scripts - Runs nginx and backend node as 'npmuser' - Changes ownership of files required at startup
This commit is contained in:
		| @@ -70,6 +70,8 @@ services: | |||||||
|       - ./letsencrypt:/etc/letsencrypt |       - ./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. Bring up your stack by running | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
|   | |||||||
| @@ -46,6 +46,8 @@ const internalCertificate = { | |||||||
|  |  | ||||||
| 			const cmd = certbotCommand + ' renew --non-interactive --quiet ' + | 			const cmd = certbotCommand + ' renew --non-interactive --quiet ' + | ||||||
| 				'--config "' + letsencryptConfig + '" ' + | 				'--config "' + letsencryptConfig + '" ' + | ||||||
|  | 				'--work-dir "/tmp/letsencrypt-lib" ' + | ||||||
|  | 				'--logs-dir "/tmp/letsencrypt-log" ' + | ||||||
| 				'--preferred-challenges "dns,http" ' + | 				'--preferred-challenges "dns,http" ' + | ||||||
| 				'--disable-hook-validation ' + | 				'--disable-hook-validation ' + | ||||||
| 				(letsencryptStaging ? '--staging' : ''); | 				(letsencryptStaging ? '--staging' : ''); | ||||||
| @@ -833,6 +835,8 @@ const internalCertificate = { | |||||||
|  |  | ||||||
| 		const cmd = certbotCommand + ' certonly ' + | 		const cmd = certbotCommand + ' certonly ' + | ||||||
| 			'--config "' + letsencryptConfig + '" ' + | 			'--config "' + letsencryptConfig + '" ' + | ||||||
|  | 			'--work-dir "/tmp/letsencrypt-lib" ' + | ||||||
|  | 			'--logs-dir "/tmp/letsencrypt-log" ' + | ||||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | 			'--cert-name "npm-' + certificate.id + '" ' + | ||||||
| 			'--agree-tos ' + | 			'--agree-tos ' + | ||||||
| 			'--authenticator webroot ' + | 			'--authenticator webroot ' + | ||||||
| @@ -878,6 +882,8 @@ const internalCertificate = { | |||||||
|  |  | ||||||
| 		let mainCmd = certbotCommand + ' certonly ' + | 		let mainCmd = certbotCommand + ' certonly ' + | ||||||
| 			'--config "' + letsencryptConfig + '" ' + | 			'--config "' + letsencryptConfig + '" ' + | ||||||
|  | 			'--work-dir "/tmp/letsencrypt-lib" ' + | ||||||
|  | 			'--logs-dir "/tmp/letsencrypt-log" ' + | ||||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | 			'--cert-name "npm-' + certificate.id + '" ' + | ||||||
| 			'--agree-tos ' + | 			'--agree-tos ' + | ||||||
| 			'--email "' + certificate.meta.letsencrypt_email + '" ' + | 			'--email "' + certificate.meta.letsencrypt_email + '" ' + | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ services: | |||||||
|     networks: |     networks: | ||||||
|       - nginx_proxy_manager |       - nginx_proxy_manager | ||||||
|     environment: |     environment: | ||||||
|  |       PUID: 1000 | ||||||
|  |       PGID: 1000 | ||||||
|       NODE_ENV: "development" |       NODE_ENV: "development" | ||||||
|       FORCE_COLOR: 1 |       FORCE_COLOR: 1 | ||||||
|       DEVELOPMENT: "true" |       DEVELOPMENT: "true" | ||||||
|   | |||||||
							
								
								
									
										29
									
								
								docker/rootfs/bin/common.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								docker/rootfs/bin/common.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | CYAN='\E[1;36m' | ||||||
|  | BLUE='\E[1;34m' | ||||||
|  | YELLOW='\E[1;33m' | ||||||
|  | RED='\E[1;31m' | ||||||
|  | RESET='\E[0m' | ||||||
|  | export CYAN BLUE YELLOW RED RESET | ||||||
|  |  | ||||||
|  | log_info () { | ||||||
|  | 	echo -e "${BLUE}❯ ${CYAN}$1${RESET}" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | log_error () { | ||||||
|  | 	echo -e "${RED}❯ $1${RESET}" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # The `run` file will only execute 1 line so this helps keep things | ||||||
|  | # logically separated | ||||||
|  |  | ||||||
|  | log_fatal () { | ||||||
|  | 	echo -e "${RED}--------------------------------------${RESET}" | ||||||
|  | 	echo -e "${RED}ERROR: $1${RESET}" | ||||||
|  | 	echo -e "${RED}--------------------------------------${RESET}" | ||||||
|  | 	/run/s6/basedir/bin/halt | ||||||
|  | 	exit 1 | ||||||
|  | } | ||||||
| @@ -1,46 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
|  |  | ||||||
| # This command reads the `DISABLE_IPV6` env var and will either enable |  | ||||||
| # or disable ipv6 in all nginx configs based on this setting. |  | ||||||
|  |  | ||||||
| # Lowercase |  | ||||||
| DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]') |  | ||||||
|  |  | ||||||
| CYAN='\E[1;36m' |  | ||||||
| BLUE='\E[1;34m' |  | ||||||
| YELLOW='\E[1;33m' |  | ||||||
| RED='\E[1;31m' |  | ||||||
| RESET='\E[0m' |  | ||||||
|  |  | ||||||
| FOLDER=$1 |  | ||||||
| if [ "$FOLDER" == "" ]; then |  | ||||||
| 	echo -e "${RED}❯ $0 requires a absolute folder path as the first argument!${RESET}" |  | ||||||
| 	echo -e "${YELLOW}  ie: $0 /data/nginx${RESET}" |  | ||||||
| 	exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| FILES=$(find "$FOLDER" -type f -name "*.conf") |  | ||||||
| if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; then |  | ||||||
| 	# IPV6 is disabled |  | ||||||
| 	echo "Disabling IPV6 in hosts" |  | ||||||
| 	echo -e "${BLUE}❯ ${CYAN}Disabling IPV6 in hosts: ${YELLOW}${FOLDER}${RESET}" |  | ||||||
|  |  | ||||||
| 	# Iterate over configs and run the regex |  | ||||||
| 	for FILE in $FILES |  | ||||||
| 	do |  | ||||||
| 		echo -e "  ${BLUE}❯ ${YELLOW}${FILE}${RESET}" |  | ||||||
| 		sed -E -i 's/^([^#]*)listen \[::\]/\1#listen [::]/g' "$FILE" |  | ||||||
| 	done |  | ||||||
|  |  | ||||||
| else |  | ||||||
| 	# IPV6 is enabled |  | ||||||
| 	echo -e "${BLUE}❯ ${CYAN}Enabling IPV6 in hosts: ${YELLOW}${FOLDER}${RESET}" |  | ||||||
|  |  | ||||||
| 	# Iterate over configs and run the regex |  | ||||||
| 	for FILE in $FILES |  | ||||||
| 	do |  | ||||||
| 		echo -e "  ${BLUE}❯ ${YELLOW}${FILE}${RESET}" |  | ||||||
| 		sed -E -i 's/^(\s*)#listen \[::\]/\1listen [::]/g' "$FILE" |  | ||||||
| 	done |  | ||||||
|  |  | ||||||
| fi |  | ||||||
| @@ -1,7 +1,6 @@ | |||||||
| # run nginx in foreground | # run nginx in foreground | ||||||
| daemon off; | daemon off; | ||||||
|  | pid /run/nginx/nginx.pid; | ||||||
| user root; |  | ||||||
|  |  | ||||||
| # Set number of worker processes automatically based on number of CPU cores. | # Set number of worker processes automatically based on number of CPU cores. | ||||||
| worker_processes auto; | worker_processes auto; | ||||||
| @@ -57,7 +56,7 @@ http { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	# Real IP Determination | 	# Real IP Determination | ||||||
| 	 |  | ||||||
| 	# Local subnets: | 	# Local subnets: | ||||||
| 	set_real_ip_from 10.0.0.0/8; | 	set_real_ip_from 10.0.0.0/8; | ||||||
| 	set_real_ip_from 172.16.0.0/12; # Includes Docker subnet | 	set_real_ip_from 172.16.0.0/12; # Includes Docker subnet | ||||||
|   | |||||||
| @@ -3,17 +3,20 @@ | |||||||
|  |  | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
| echo "❯ Starting backend ..." | . /bin/common.sh | ||||||
|  |  | ||||||
|  | log_info 'Starting backend ...' | ||||||
|  |  | ||||||
| if [ "$DEVELOPMENT" == "true" ]; then | if [ "$DEVELOPMENT" == "true" ]; then | ||||||
| 	cd /app || exit 1 | 	cd /app || exit 1 | ||||||
| 	# If yarn install fails: add --verbose --network-concurrency 1 | 	# If yarn install fails: add --verbose --network-concurrency 1 | ||||||
| 	yarn install | 	s6-setuidgid npmuser yarn install | ||||||
| 	node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js | 	exec s6-setuidgid npmuser node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js | ||||||
| else | else | ||||||
| 	cd /app || exit 1 | 	cd /app || exit 1 | ||||||
| 	while : | 	while : | ||||||
| 	do | 	do | ||||||
| 		node --abort_on_uncaught_exception --max_old_space_size=250 index.js | 		s6-setuidgid npmuser node --abort_on_uncaught_exception --max_old_space_size=250 index.js | ||||||
| 		sleep 1 | 		sleep 1 | ||||||
| 	done | 	done | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -6,10 +6,16 @@ set -e | |||||||
| # This service is DEVELOPMENT only. | # This service is DEVELOPMENT only. | ||||||
|  |  | ||||||
| if [ "$DEVELOPMENT" == "true" ]; then | if [ "$DEVELOPMENT" == "true" ]; then | ||||||
|  | 	. /bin/common.sh | ||||||
| 	cd /app/frontend || exit 1 | 	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 | 	# If yarn install fails: add --verbose --network-concurrency 1 | ||||||
| 	yarn install | 	s6-setuidgid npmuser yarn install | ||||||
| 	yarn watch | 	exec s6-setuidgid npmuser yarn watch | ||||||
| else | else | ||||||
| 	exit 0 | 	exit 0 | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -3,5 +3,8 @@ | |||||||
|  |  | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
| echo "❯ Starting nginx ..." | . /bin/common.sh | ||||||
| exec nginx |  | ||||||
|  | log_info 'Starting nginx ...' | ||||||
|  |  | ||||||
|  | exec s6-setuidgid npmuser nginx | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | . /bin/common.sh | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | . /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 | ||||||
|  | . /etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh | ||||||
|  | . /etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh | ||||||
|  | . /etc/s6-overlay/s6-rc.d/prepare/90-banner.sh | ||||||
							
								
								
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										18
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/10-npmuser.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | PUID=${PUID:-911} | ||||||
|  | PGID=${PGID:-911} | ||||||
|  |  | ||||||
|  | # Add npmuser user | ||||||
|  | log_info 'Creating npmuser ...' | ||||||
|  |  | ||||||
|  | groupmod -g 1000 users || exit 1 | ||||||
|  | useradd -u "${PUID}" -U -d /data -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 | ||||||
							
								
								
									
										41
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										41
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/20-paths.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | log_info 'Checking paths ...' | ||||||
|  |  | ||||||
|  | # Ensure /data is mounted | ||||||
|  | if [ ! -d '/data' ]; then | ||||||
|  | 	log_fatal '/data is not mounted! Check your docker configuration.' | ||||||
|  | fi | ||||||
|  | # Ensure /etc/letsencrypt is mounted | ||||||
|  | if [ ! -d '/etc/letsencrypt' ]; then | ||||||
|  | 	log_fatal '/etc/letsencrypt is not mounted! Check your docker configuration.' | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | # Create required folders | ||||||
|  | mkdir -p \ | ||||||
|  | 	/data/nginx \ | ||||||
|  | 	/data/custom_ssl \ | ||||||
|  | 	/data/logs \ | ||||||
|  | 	/data/access \ | ||||||
|  | 	/data/nginx/default_host \ | ||||||
|  | 	/data/nginx/default_www \ | ||||||
|  | 	/data/nginx/proxy_host \ | ||||||
|  | 	/data/nginx/redirection_host \ | ||||||
|  | 	/data/nginx/stream \ | ||||||
|  | 	/data/nginx/dead_host \ | ||||||
|  | 	/data/nginx/temp \ | ||||||
|  | 	/data/letsencrypt-acme-challenge \ | ||||||
|  | 	/run/nginx \ | ||||||
|  | 	/tmp/nginx/body \ | ||||||
|  | 	/var/log/nginx \ | ||||||
|  | 	/var/lib/nginx/cache/public \ | ||||||
|  | 	/var/lib/nginx/cache/private \ | ||||||
|  | 	/var/cache/nginx/proxy_temp | ||||||
|  |  | ||||||
|  | touch /var/log/nginx/error.log || true | ||||||
|  | chmod 777 /var/log/nginx/error.log || true | ||||||
|  | chmod -R 777 /var/cache/nginx || true | ||||||
|  | chmod 644 /etc/logrotate.d/nginx-proxy-manager | ||||||
							
								
								
									
										21
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										21
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/30-ownership.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | log_info 'Setting ownership ...' | ||||||
|  |  | ||||||
|  | # root | ||||||
|  | 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 | ||||||
							
								
								
									
										17
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/40-dynamic.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | log_info 'Dynamic resolvers ...' | ||||||
|  |  | ||||||
|  | DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]') | ||||||
|  |  | ||||||
|  | # Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` | ||||||
|  | # thanks @tfmm | ||||||
|  | if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; | ||||||
|  | then | ||||||
|  | 	echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf | ||||||
|  | else | ||||||
|  | 	echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf | ||||||
|  | fi | ||||||
							
								
								
									
										36
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/50-ipv6.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | # This command reads the `DISABLE_IPV6` env var and will either enable | ||||||
|  | # or disable ipv6 in all nginx configs based on this setting. | ||||||
|  |  | ||||||
|  | log_info 'IPv6 ...' | ||||||
|  |  | ||||||
|  | # Lowercase | ||||||
|  | DISABLE_IPV6=$(echo "${DISABLE_IPV6:-}" | tr '[:upper:]' '[:lower:]') | ||||||
|  |  | ||||||
|  | process_folder () { | ||||||
|  | 	FILES=$(find "$1" -type f -name "*.conf") | ||||||
|  | 	SED_REGEX= | ||||||
|  |  | ||||||
|  | 	if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; then | ||||||
|  | 		# IPV6 is disabled | ||||||
|  | 		echo "Disabling IPV6 in hosts in: $1" | ||||||
|  | 		SED_REGEX='s/^([^#]*)listen \[::\]/\1#listen [::]/g' | ||||||
|  | 	else | ||||||
|  | 		# IPV6 is enabled | ||||||
|  | 		echo "Enabling IPV6 in hosts in: $1" | ||||||
|  | 		SED_REGEX='s/^(\s*)#listen \[::\]/\1listen [::]/g' | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	for FILE in $FILES | ||||||
|  | 	do | ||||||
|  | 		echo "- ${FILE}" | ||||||
|  | 		sed -E -i "$SED_REGEX" "$FILE" | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	# ensure the files are still owned by the npmuser | ||||||
|  | 	chown -R npmuser:npmuser "$1" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | process_folder /etc/nginx/conf.d | ||||||
|  | process_folder /data/nginx | ||||||
							
								
								
									
										30
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										30
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | # in s6, environmental variables are written as text files for s6 to monitor | ||||||
|  | # search through full-path filenames for files ending in "__FILE" | ||||||
|  | log_info 'Docker secrets ...' | ||||||
|  |  | ||||||
|  | for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do | ||||||
|  | 	echo "[secret-init] Evaluating ${FILENAME##*/} ..." | ||||||
|  |  | ||||||
|  | 	# set SECRETFILE to the contents of the full-path textfile | ||||||
|  | 	SECRETFILE=$(cat "${FILENAME}") | ||||||
|  | 	# if SECRETFILE exists / is not null | ||||||
|  | 	if [[ -f "${SECRETFILE}" ]]; then | ||||||
|  | 		# strip the appended "__FILE" from environmental variable name ... | ||||||
|  | 		STRIPFILE=$(echo "${FILENAME}" | sed "s/__FILE//g") | ||||||
|  | 		# echo "[secret-init] Set STRIPFILE to ${STRIPFILE}"  # DEBUG - rm for prod! | ||||||
|  |  | ||||||
|  | 		# ... and set value to contents of secretfile | ||||||
|  | 		# since s6 uses text files, this is effectively "export ..." | ||||||
|  | 		printf $(cat "${SECRETFILE}") > "${STRIPFILE}" | ||||||
|  | 		# echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})"  # DEBUG - rm for prod!" | ||||||
|  | 		echo "Success: ${STRIPFILE##*/} set from ${FILENAME##*/}" | ||||||
|  |  | ||||||
|  | 	else | ||||||
|  | 		echo "Cannot find secret in ${FILENAME}" | ||||||
|  | 	fi | ||||||
|  | done | ||||||
							
								
								
									
										17
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/90-banner.sh
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | #!/command/with-contenv bash | ||||||
|  | # shellcheck shell=bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | echo | ||||||
|  | echo "------------------------------------- | ||||||
|  |  _   _ ____  __  __ | ||||||
|  | | \ | |  _ \|  \/  | | ||||||
|  | |  \| | |_) | |\/| | | ||||||
|  | | |\  |  __/| |  | | | ||||||
|  | |_| \_|_|   |_|  |_| | ||||||
|  | ------------------------------------- | ||||||
|  | User UID: $(id -u npmuser) | ||||||
|  | User GID: $(id -g npmuser) | ||||||
|  | ------------------------------------- | ||||||
|  | " | ||||||
| @@ -1,93 +0,0 @@ | |||||||
| #!/command/with-contenv bash |  | ||||||
| # shellcheck shell=bash |  | ||||||
|  |  | ||||||
| set -e |  | ||||||
|  |  | ||||||
| DATA_PATH=/data |  | ||||||
|  |  | ||||||
| # Ensure /data is mounted |  | ||||||
| if [ ! -d "$DATA_PATH" ]; then |  | ||||||
| 	echo '--------------------------------------' |  | ||||||
| 	echo "ERROR: $DATA_PATH is not mounted! Check your docker configuration." |  | ||||||
| 	echo '--------------------------------------' |  | ||||||
| 	/run/s6/basedir/bin/halt |  | ||||||
| 	exit 1 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| echo "❯ Checking folder structure ..." |  | ||||||
|  |  | ||||||
| # Create required folders |  | ||||||
| mkdir -p /tmp/nginx/body \ |  | ||||||
| 	/run/nginx \ |  | ||||||
| 	/var/log/nginx \ |  | ||||||
| 	/data/nginx \ |  | ||||||
| 	/data/custom_ssl \ |  | ||||||
| 	/data/logs \ |  | ||||||
| 	/data/access \ |  | ||||||
| 	/data/nginx/default_host \ |  | ||||||
| 	/data/nginx/default_www \ |  | ||||||
| 	/data/nginx/proxy_host \ |  | ||||||
| 	/data/nginx/redirection_host \ |  | ||||||
| 	/data/nginx/stream \ |  | ||||||
| 	/data/nginx/dead_host \ |  | ||||||
| 	/data/nginx/temp \ |  | ||||||
| 	/var/lib/nginx/cache/public \ |  | ||||||
| 	/var/lib/nginx/cache/private \ |  | ||||||
| 	/var/cache/nginx/proxy_temp \ |  | ||||||
| 	/data/letsencrypt-acme-challenge |  | ||||||
|  |  | ||||||
| touch /var/log/nginx/error.log && chmod 777 /var/log/nginx/error.log && chmod -R 777 /var/cache/nginx |  | ||||||
| chown root /tmp/nginx |  | ||||||
|  |  | ||||||
| # Dynamically generate resolvers file, if resolver is IPv6, enclose in `[]` |  | ||||||
| # thanks @tfmm |  | ||||||
| if [ "$DISABLE_IPV6" == "true" ] || [ "$DISABLE_IPV6" == "on" ] || [ "$DISABLE_IPV6" == "1" ] || [ "$DISABLE_IPV6" == "yes" ]; |  | ||||||
| then |  | ||||||
| 	echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) ipv6=off valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf |  | ||||||
| else |  | ||||||
| 	echo resolver "$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf) valid=10s;" > /etc/nginx/conf.d/include/resolvers.conf |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| echo "Changing ownership of /data/logs to $(id -u):$(id -g)" |  | ||||||
| chown -R "$(id -u):$(id -g)" /data/logs |  | ||||||
|  |  | ||||||
| # Handle IPV6 settings |  | ||||||
| /bin/handle-ipv6-setting /etc/nginx/conf.d |  | ||||||
| /bin/handle-ipv6-setting /data/nginx |  | ||||||
|  |  | ||||||
| # ref: https://github.com/linuxserver/docker-baseimage-alpine/blob/master/root/etc/cont-init.d/01-envfile |  | ||||||
|  |  | ||||||
| # in s6, environmental variables are written as text files for s6 to monitor |  | ||||||
| # search through full-path filenames for files ending in "__FILE" |  | ||||||
| echo "❯ Secrets-init ..." |  | ||||||
| for FILENAME in $(find /var/run/s6/container_environment/ | grep "__FILE$"); do |  | ||||||
| 	echo "[secret-init] Evaluating ${FILENAME##*/} ..." |  | ||||||
|  |  | ||||||
| 	# set SECRETFILE to the contents of the full-path textfile |  | ||||||
| 	SECRETFILE=$(cat "${FILENAME}") |  | ||||||
| 	# if SECRETFILE exists / is not null |  | ||||||
| 	if [[ -f "${SECRETFILE}" ]]; then |  | ||||||
| 		# strip the appended "__FILE" from environmental variable name ... |  | ||||||
| 		STRIPFILE=$(echo "${FILENAME}" | sed "s/__FILE//g") |  | ||||||
| 		# echo "[secret-init] Set STRIPFILE to ${STRIPFILE}"  # DEBUG - rm for prod! |  | ||||||
|  |  | ||||||
| 		# ... and set value to contents of secretfile |  | ||||||
| 		# since s6 uses text files, this is effectively "export ..." |  | ||||||
| 		printf $(cat "${SECRETFILE}") > "${STRIPFILE}" |  | ||||||
| 		# echo "[secret-init] Set ${STRIPFILE##*/} to $(cat ${STRIPFILE})"  # DEBUG - rm for prod!" |  | ||||||
| 		echo "[secret-init] Success! ${STRIPFILE##*/} set from ${FILENAME##*/}" |  | ||||||
|  |  | ||||||
| 	else |  | ||||||
| 		echo "[secret-init] cannot find secret in ${FILENAME}" |  | ||||||
| 	fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| echo |  | ||||||
| echo "------------------------------------- |  | ||||||
|  _   _ ____  __  __ |  | ||||||
| | \ | |  _ \|  \/  | |  | ||||||
| |  \| | |_) | |\/| | |  | ||||||
| | |\  |  __/| |  | | |  | ||||||
| |_| \_|_|   |_|  |_| |  | ||||||
| ------------------------------------- |  | ||||||
| " |  | ||||||
| @@ -1,2 +1,2 @@ | |||||||
| # shellcheck shell=bash | # shellcheck shell=bash | ||||||
| /etc/s6-overlay/s6-rc.d/prepare/script.sh | /etc/s6-overlay/s6-rc.d/prepare/00-all.sh | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ services: | |||||||
|  |  | ||||||
|     # Uncomment the next line if you uncomment anything in the section |     # Uncomment the next line if you uncomment anything in the section | ||||||
|     # environment: |     # environment: | ||||||
|       # Uncomment this if you want to change the location of  |       # Uncomment this if you want to change the location of | ||||||
|       # the SQLite DB file within the container |       # the SQLite DB file within the container | ||||||
|       # DB_SQLITE_FILE: "/data/database.sqlite" |       # DB_SQLITE_FILE: "/data/database.sqlite" | ||||||
|  |  | ||||||
| @@ -64,6 +64,10 @@ services: | |||||||
|       # Add any other Stream port you want to expose |       # Add any other Stream port you want to expose | ||||||
|       # - '21:21' # FTP |       # - '21:21' # FTP | ||||||
|     environment: |     environment: | ||||||
|  |       # Unix user and group IDs, optional | ||||||
|  |       PUID: 1000 | ||||||
|  |       PGID: 1000 | ||||||
|  |       # Mysql/Maria connection parameters: | ||||||
|       DB_MYSQL_HOST: "db" |       DB_MYSQL_HOST: "db" | ||||||
|       DB_MYSQL_PORT: 3306 |       DB_MYSQL_PORT: 3306 | ||||||
|       DB_MYSQL_USER: "npm" |       DB_MYSQL_USER: "npm" | ||||||
|   | |||||||
| @@ -9,3 +9,4 @@ This project will automatically update any databases or other requirements so yo | |||||||
| any crazy instructions. These steps above will pull the latest updates and recreate the docker | any crazy instructions. These steps above will pull the latest updates and recreate the docker | ||||||
| containers. | containers. | ||||||
|  |  | ||||||
|  | See the [list of releases](https://github.com/NginxProxyManager/nginx-proxy-manager/releases) for any upgrade steps specific to each release. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user