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 | ||||
| ``` | ||||
|  | ||||
| This is the bare minimum configuration required. See the [documentation](https://nginxproxymanager.com/setup/) for more. | ||||
|  | ||||
| 3. Bring up your stack by running | ||||
|  | ||||
| ```bash | ||||
|   | ||||
| @@ -46,6 +46,8 @@ const internalCertificate = { | ||||
|  | ||||
| 			const cmd = certbotCommand + ' renew --non-interactive --quiet ' + | ||||
| 				'--config "' + letsencryptConfig + '" ' + | ||||
| 				'--work-dir "/tmp/letsencrypt-lib" ' + | ||||
| 				'--logs-dir "/tmp/letsencrypt-log" ' + | ||||
| 				'--preferred-challenges "dns,http" ' + | ||||
| 				'--disable-hook-validation ' + | ||||
| 				(letsencryptStaging ? '--staging' : ''); | ||||
| @@ -833,6 +835,8 @@ const internalCertificate = { | ||||
|  | ||||
| 		const cmd = certbotCommand + ' certonly ' + | ||||
| 			'--config "' + letsencryptConfig + '" ' + | ||||
| 			'--work-dir "/tmp/letsencrypt-lib" ' + | ||||
| 			'--logs-dir "/tmp/letsencrypt-log" ' + | ||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | ||||
| 			'--agree-tos ' + | ||||
| 			'--authenticator webroot ' + | ||||
| @@ -878,6 +882,8 @@ const internalCertificate = { | ||||
|  | ||||
| 		let mainCmd = certbotCommand + ' certonly ' + | ||||
| 			'--config "' + letsencryptConfig + '" ' + | ||||
| 			'--work-dir "/tmp/letsencrypt-lib" ' + | ||||
| 			'--logs-dir "/tmp/letsencrypt-log" ' + | ||||
| 			'--cert-name "npm-' + certificate.id + '" ' + | ||||
| 			'--agree-tos ' + | ||||
| 			'--email "' + certificate.meta.letsencrypt_email + '" ' + | ||||
|   | ||||
| @@ -14,6 +14,8 @@ services: | ||||
|     networks: | ||||
|       - nginx_proxy_manager | ||||
|     environment: | ||||
|       PUID: 1000 | ||||
|       PGID: 1000 | ||||
|       NODE_ENV: "development" | ||||
|       FORCE_COLOR: 1 | ||||
|       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 | ||||
| daemon off; | ||||
|  | ||||
| user root; | ||||
| pid /run/nginx/nginx.pid; | ||||
|  | ||||
| # Set number of worker processes automatically based on number of CPU cores. | ||||
| worker_processes auto; | ||||
| @@ -57,7 +56,7 @@ http { | ||||
| 	} | ||||
|  | ||||
| 	# Real IP Determination | ||||
| 	 | ||||
|  | ||||
| 	# Local subnets: | ||||
| 	set_real_ip_from 10.0.0.0/8; | ||||
| 	set_real_ip_from 172.16.0.0/12; # Includes Docker subnet | ||||
|   | ||||
| @@ -3,17 +3,20 @@ | ||||
|  | ||||
| set -e | ||||
|  | ||||
| echo "❯ Starting backend ..." | ||||
| . /bin/common.sh | ||||
|  | ||||
| log_info 'Starting backend ...' | ||||
|  | ||||
| if [ "$DEVELOPMENT" == "true" ]; then | ||||
| 	cd /app || exit 1 | ||||
| 	# If yarn install fails: add --verbose --network-concurrency 1 | ||||
| 	yarn install | ||||
| 	node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js | ||||
| 	s6-setuidgid npmuser yarn install | ||||
| 	exec s6-setuidgid npmuser node --max_old_space_size=250 --abort_on_uncaught_exception node_modules/nodemon/bin/nodemon.js | ||||
| else | ||||
| 	cd /app || exit 1 | ||||
| 	while : | ||||
| 	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 | ||||
| 	done | ||||
| fi | ||||
|   | ||||
| @@ -6,10 +6,16 @@ set -e | ||||
| # This service is DEVELOPMENT only. | ||||
|  | ||||
| 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 | ||||
| 	yarn install | ||||
| 	yarn watch | ||||
| 	s6-setuidgid npmuser yarn install | ||||
| 	exec s6-setuidgid npmuser yarn watch | ||||
| else | ||||
| 	exit 0 | ||||
| fi | ||||
|   | ||||
| @@ -3,5 +3,8 @@ | ||||
|  | ||||
| set -e | ||||
|  | ||||
| echo "❯ Starting nginx ..." | ||||
| exec nginx | ||||
| . /bin/common.sh | ||||
|  | ||||
| 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 | ||||
| /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 | ||||
|     # 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 | ||||
|       # DB_SQLITE_FILE: "/data/database.sqlite" | ||||
|  | ||||
| @@ -64,6 +64,10 @@ 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 | ||||
|       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 | ||||
| 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