Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for chaning the HTTP and HTTPS port that hosts will listen on #4127

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions backend/internal/nginx.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ const config = require('../lib/config');
const utils = require('../lib/utils');
const error = require('../lib/error');

/**
*
* @param {int} user_port
* @param {int} default_port
* @returns {int} port
*/
const validatePort = (user_port, default_port) => {
if (isNaN(user_port) || user_port < 1 || user_port > 65535) {
console.error(`Environment variable HTTP_PORT must be an integer between 1 and 65535 (got: ${user_port}). Using default port ${default_port}`);
return default_port;
}
return user_port;
};

const internalNginx = {

/**
Expand Down Expand Up @@ -232,8 +246,10 @@ const internalNginx = {
locationsPromise = Promise.resolve();
}

// Set the IPv6 setting for the host
host.ipv6 = internalNginx.ipv6Enabled();
// Set the IPv6 and port setting for the host
host.ipv6 = internalNginx.ipv6Enabled();
host.http_port = internalNginx.httpPort();
host.https_port = internalNginx.httpsPort();

locationsPromise.then(() => {
renderEngine
Expand Down Expand Up @@ -287,7 +303,9 @@ const internalNginx = {
return;
}

certificate.ipv6 = internalNginx.ipv6Enabled();
certificate.ipv6 = internalNginx.ipv6Enabled();
certificate.http_port = internalNginx.httpPort();
certificate.https_port = internalNginx.httpsPort();

renderEngine
.parseAndRender(template, certificate)
Expand Down Expand Up @@ -432,7 +450,30 @@ const internalNginx = {
}

return true;
},

/**
* @returns {integer}
*/
httpPort: function () {
if (typeof process.env.HTTP_PORT !== 'undefined') {
let httpPort = parseInt(process.env.HTTP_PORT);
return validatePort(httpPort, 443);
}
return 80;
},

/**
* @returns {integer}
*/
httpsPort: function () {
if (typeof process.env.HTTPS_PORT !== 'undefined') {
let httpPort = parseInt(process.env.HTTPS_PORT);
return validatePort(httpPort, 443);
}
return 80;
}

};

module.exports = internalNginx;
12 changes: 6 additions & 6 deletions backend/templates/_listen.conf
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
listen 80;
listen {{ http_port }};
{% if ipv6 -%}
listen [::]:80;
listen [::]:{{ http_port }};
{% else -%}
#listen [::]:80;
#listen [::]:{{ http_port }};
{% endif %}
{% if certificate -%}
listen 443 ssl;
listen {{ https_port }} ssl;
{% if ipv6 -%}
listen [::]:443 ssl;
listen [::]:{{ https_port }} ssl;
{% else -%}
#listen [::]:443;
#listen [::]:{{ https_port }};
{% endif %}
{% endif %}
server_name {{ domain_names | join: " " }};
Expand Down
2 changes: 2 additions & 0 deletions docker/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ services:
DB_MYSQL_NAME: 'npm'
# DB_SQLITE_FILE: "/data/database.sqlite"
# DISABLE_IPV6: "true"
# HTTP_PORT: "1234"
# HTTPS_PORT: "5678"
# Required for DNS Certificate provisioning testing:
LE_SERVER: 'https://ca.internal/acme/acme/directory'
REQUESTS_CA_BUNDLE: '/etc/ssl/certs/NginxProxyManager.crt'
Expand Down
1 change: 1 addition & 0 deletions docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/00-all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ fi
. /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/55-http-https-port.sh
. /etc/s6-overlay/s6-rc.d/prepare/60-secrets.sh
. /etc/s6-overlay/s6-rc.d/prepare/90-banner.sh
62 changes: 62 additions & 0 deletions docker/rootfs/etc/s6-overlay/s6-rc.d/prepare/55-http-https-port.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/command/with-contenv bash
# shellcheck shell=bash

# This command reads the `HTTP_PORT` and `HTTPS_PORT` env vars and will rerender
# the nginx files to the port defined in these variables

set -e

log_info 'HTTP_PORT ...'

DEFAULT_HTTP_PORT="80"
DEFAULT_HTTPS_PORT="443"

# Make sure HTTP_PORT and HTTPS_PORT are set correctly
case "$HTTP_PORT" in
''|*[!0-9]*)
echo "Could not parse HTTP_PORT as integer (got \"$HTTP_PORT\")."
echo "Using default http port \"$DEFAULT_HTTP_PORT\""
HTTP_PORT="$DEFAULT_HTTP_PORT"
;;
*) true ;;
esac
if [ "$HTTP_PORT" -lt "1" ] || [ "$HTTP_PORT" -gt "65535" ]; then
echo "HTTP_PORT must be between 1 and 65535 (got \"$HTTP_PORT\")."
echo "Using default http port \"$DEFAULT_HTTP_PORT\""
HTTP_PORT="$DEFAULT_HTTP_PORT"
fi
case "$HTTPS_PORT" in
''|*[!0-9]*)
echo "Could not parse HTTPS_PORT as integer (got \"$HTTPS_PORT\")."
echo "Using default https port \"$DEFAULT_HTTPS_PORT\""
HTTPS_PORT="$DEFAULT_HTTPS_PORT"
;;
*) true ;;
esac
if [ "$HTTPS_PORT" -lt "1" ] || [ "$HTTPS_PORT" -gt "65535" ]; then
echo "HTTPS_PORT must be between 1 and 65535 (got \"$HTTPS_PORT\")."
echo "Using default https port \"$DEFAULT_HTTPS_PORT\""
HTTPS_PORT="$DEFAULT_HTTPS_PORT"
fi

process_folder () {
FILES=$(find "$1" -type f -name "*.conf")

HTTP_SED_REGEX='/ssl/! s/listen (\[::\]:)?[0-9]+/listen \1'$HTTP_PORT'/g'
HTTPS_SED_REGEX='/ssl/ s/listen (\[::\]:)?[0-9]+/listen \1'$HTTPS_PORT'/g'

echo "Setting HTTP listen port to $HTTP_PORT and HTTPS listen port to $HTTPS_PORT in: $1"

for FILE in $FILES
do
echo "- ${FILE}"
echo "$(sed -E "$HTTP_SED_REGEX" "$FILE")" > $FILE
echo "$(sed -E "$HTTPS_SED_REGEX" "$FILE")" > $FILE
done

# ensure the files are still owned by the npm user
chown -R "$PUID:$PGID" "$1"
}

process_folder /etc/nginx/conf.d
process_folder /data/nginx
12 changes: 12 additions & 0 deletions docs/src/advanced-config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,18 @@ The easy fix is to add a Docker environment variable to the Nginx Proxy Manager
DISABLE_IPV6: 'true'
```

## Chaning the HTTP and HTTPS Listen Port

If you are unable to configure the port mapping within Docker (eg. when using
`hostNetwork: true`) you can change the port that proxy-hosts and
redirection-hosts listen on by setting the environment variables `HTTP_PORT` and
`HTTPS_PORT`:

```yml
environment:
HTTP_PORT: "1234"
HTTPS_PORT: "5678"
```

## Custom Nginx Configurations

Expand Down