Compare commits

..

5 Commits
2.0.2 ... 2.0.3

17 changed files with 202 additions and 68 deletions

View File

@ -29,4 +29,11 @@ ADD knexfile.js /app/knexfile.js
VOLUME [ "/data", "/etc/letsencrypt" ] VOLUME [ "/data", "/etc/letsencrypt" ]
CMD [ "/init" ] CMD [ "/init" ]
# Ports
EXPOSE 80
EXPOSE 81
EXPOSE 443
EXPOSE 9876
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1 HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1

View File

@ -29,4 +29,10 @@ ADD knexfile.js /app/knexfile.js
VOLUME [ "/data", "/etc/letsencrypt" ] VOLUME [ "/data", "/etc/letsencrypt" ]
CMD [ "/init" ] CMD [ "/init" ]
# Ports
EXPOSE 80
EXPOSE 81
EXPOSE 443
EXPOSE 9876
HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1 HEALTHCHECK --interval=15s --timeout=3s CMD curl -f http://localhost:9876/health || exit 1

View File

@ -2,7 +2,7 @@
# Nginx Proxy Manager # Nginx Proxy Manager
![Version](https://img.shields.io/badge/version-2.0.2-green.svg?style=for-the-badge) ![Version](https://img.shields.io/badge/version-2.0.3-green.svg?style=for-the-badge)
![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge)
![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge)

26
bin/migrate_create Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
if [ "$1" == "" ]; then
echo "Error: migrate name must be specified as first arg"
exit 1
else
# Code path
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
if hash realpath 2>/dev/null; then
export CODEBASE=$(realpath $SCRIPT_DIR/..)
elif hash grealpath 2>/dev/null; then
export CODEBASE=$(grealpath $SCRIPT_DIR/..)
else
export CODEBASE=$(readlink -e $SCRIPT_DIR/..)
fi
if [ -z "$CODEBASE" ]; then
echo "Unable to determine absolute codebase directory"
exit 1
fi
cd "$CODEBASE"
sudo /usr/local/bin/docker-compose run --rm --no-deps app node node_modules/knex/bin/cli.js migrate:make "$1"
exit $?
fi

View File

@ -2,7 +2,7 @@
# Nginx Proxy Manager # Nginx Proxy Manager
![Version](https://img.shields.io/badge/version-2.0.0-green.svg?style=for-the-badge) ![Version](https://img.shields.io/badge/version-2.0.3-green.svg?style=for-the-badge)
![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Stars](https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge)
![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge) ![Pulls](https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge)

View File

@ -1,6 +1,6 @@
{ {
"name": "nginx-proxy-manager", "name": "nginx-proxy-manager",
"version": "2.0.2", "version": "2.0.3",
"description": "A beautiful interface for creating Nginx endpoints", "description": "A beautiful interface for creating Nginx endpoints",
"main": "src/backend/index.js", "main": "src/backend/index.js",
"devDependencies": { "devDependencies": {

View File

@ -3,4 +3,9 @@
mkdir -p /data/letsencrypt-acme-challenge mkdir -p /data/letsencrypt-acme-challenge
cd /app cd /app
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
while :
do
node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js
sleep 1
done

View File

@ -4,6 +4,7 @@ const fs = require('fs');
const logger = require('./logger').import; const logger = require('./logger').import;
const utils = require('./lib/utils'); const utils = require('./lib/utils');
const batchflow = require('batchflow'); const batchflow = require('batchflow');
const debug_mode = process.env.NODE_ENV !== 'production';
const internalProxyHost = require('./internal/proxy-host'); const internalProxyHost = require('./internal/proxy-host');
const internalRedirectionHost = require('./internal/redirection-host'); const internalRedirectionHost = require('./internal/redirection-host');
@ -534,6 +535,10 @@ module.exports = function () {
); );
} else { } else {
if (debug_mode) {
logger.debug('Importer skipped');
}
resolve(); resolve();
} }
}); });

View File

@ -8,4 +8,5 @@ module.exports = {
nginx: new Signale({scope: 'Nginx '}), nginx: new Signale({scope: 'Nginx '}),
ssl: new Signale({scope: 'SSL '}), ssl: new Signale({scope: 'SSL '}),
import: new Signale({scope: 'Importer'}), import: new Signale({scope: 'Importer'}),
setup: new Signale({scope: 'Setup '})
}; };

View File

@ -0,0 +1,37 @@
'use strict';
const migrate_name = 'websockets';
const logger = require('../logger').migrate;
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.up = function (knex/*, Promise*/) {
logger.info('[' + migrate_name + '] Migrating Up...');
return knex.schema.table('proxy_host', function (proxy_host) {
proxy_host.integer('allow_websocket_upgrade').notNull().unsigned().defaultTo(0);
})
.then(() => {
logger.info('[' + migrate_name + '] proxy_host Table altered');
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @param {Promise} Promise
* @returns {Promise}
*/
exports.down = function (knex, Promise) {
logger.warn('[' + migrate_name + '] You can\'t migrate down this one.');
return Promise.resolve(true);
};

View File

@ -39,6 +39,11 @@
"caching_enabled": { "caching_enabled": {
"$ref": "../definitions.json#/definitions/caching_enabled" "$ref": "../definitions.json#/definitions/caching_enabled"
}, },
"allow_websocket_upgrade": {
"description": "Allow Websocket Upgrade for all paths",
"example": true,
"type": "boolean"
},
"access_list_id": { "access_list_id": {
"$ref": "../definitions.json#/definitions/access_list_id" "$ref": "../definitions.json#/definitions/access_list_id"
}, },
@ -80,6 +85,9 @@
"caching_enabled": { "caching_enabled": {
"$ref": "#/definitions/caching_enabled" "$ref": "#/definitions/caching_enabled"
}, },
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"access_list_id": { "access_list_id": {
"$ref": "#/definitions/access_list_id" "$ref": "#/definitions/access_list_id"
}, },
@ -148,6 +156,9 @@
"caching_enabled": { "caching_enabled": {
"$ref": "#/definitions/caching_enabled" "$ref": "#/definitions/caching_enabled"
}, },
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"access_list_id": { "access_list_id": {
"$ref": "#/definitions/access_list_id" "$ref": "#/definitions/access_list_id"
}, },
@ -200,6 +211,9 @@
"caching_enabled": { "caching_enabled": {
"$ref": "#/definitions/caching_enabled" "$ref": "#/definitions/caching_enabled"
}, },
"allow_websocket_upgrade": {
"$ref": "#/definitions/allow_websocket_upgrade"
},
"access_list_id": { "access_list_id": {
"$ref": "#/definitions/access_list_id" "$ref": "#/definitions/access_list_id"
}, },

View File

@ -3,10 +3,11 @@
const fs = require('fs'); const fs = require('fs');
const NodeRSA = require('node-rsa'); const NodeRSA = require('node-rsa');
const config = require('config'); const config = require('config');
const logger = require('./logger').global; const logger = require('./logger').setup;
const userModel = require('./models/user'); const userModel = require('./models/user');
const userPermissionModel = require('./models/user_permission'); const userPermissionModel = require('./models/user_permission');
const authModel = require('./models/auth'); const authModel = require('./models/auth');
const debug_mode = process.env.NODE_ENV !== 'production';
module.exports = function () { module.exports = function () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -22,6 +23,9 @@ module.exports = function () {
config_data = require(filename); config_data = require(filename);
} catch (err) { } catch (err) {
// do nothing // do nothing
if (debug_mode) {
logger.debug(filename + ' config file could not be required');
}
} }
// Now create the keys and save them in the config. // Now create the keys and save them in the config.
@ -40,12 +44,18 @@ module.exports = function () {
reject(err); reject(err);
} else { } else {
logger.info('Wrote JWT key pair to config file: ' + filename); logger.info('Wrote JWT key pair to config file: ' + filename);
config.util.loadFileConfigs();
resolve(); logger.warn('Restarting interface to apply new configuration');
process.exit(0);
} }
}); });
} else { } else {
// JWT key pair exists // JWT key pair exists
if (debug_mode) {
logger.debug('JWT Keypair already exists');
}
resolve(); resolve();
} }
}) })
@ -54,7 +64,8 @@ module.exports = function () {
.query() .query()
.select(userModel.raw('COUNT(`id`) as `count`')) .select(userModel.raw('COUNT(`id`) as `count`'))
.where('is_deleted', 0) .where('is_deleted', 0)
.first('count') .first();
})
.then(row => { .then(row => {
if (!row.count) { if (!row.count) {
// Create a new user and set password // Create a new user and set password
@ -95,8 +106,12 @@ module.exports = function () {
certificates: 'manage' certificates: 'manage'
}); });
}); });
})
.then(() => {
logger.info('Initial setup completed');
}); });
} else if (debug_mode) {
logger.debug('Admin user setup not required');
} }
}); });
});
}; };

View File

@ -22,6 +22,12 @@ server {
{% include "_forced_ssl.conf" %} {% include "_forced_ssl.conf" %}
{% if allow_websocket_upgrade == 1 or allow_websocket_upgrade == true %}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
{% endif %}
# Proxy! # Proxy!
include conf.d/include/proxy.conf; include conf.d/include/proxy.conf;
} }

View File

@ -50,6 +50,15 @@
</label> </label>
</div> </div>
</div> </div>
<div class="col-sm-12 col-md-12">
<div class="form-group">
<label class="custom-switch">
<input type="checkbox" class="custom-switch-input" name="allow_websocket_upgrade" value="1"<%- allow_websocket_upgrade ? ' checked' : '' %>>
<span class="custom-switch-indicator"></span>
<span class="custom-switch-description"><%- i18n('proxy-hosts', 'allow-websocket-upgrade') %></span>
</label>
</div>
</div>
<div class="col-sm-12 col-md-12"> <div class="col-sm-12 col-md-12">
<div class="form-group"> <div class="form-group">
<label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label> <label class="form-label"><%- i18n('proxy-hosts', 'access-list') %></label>

View File

@ -57,6 +57,7 @@ module.exports = Mn.View.extend({
data.forward_port = parseInt(data.forward_port, 10); data.forward_port = parseInt(data.forward_port, 10);
data.block_exploits = !!data.block_exploits; data.block_exploits = !!data.block_exploits;
data.caching_enabled = !!data.caching_enabled; data.caching_enabled = !!data.caching_enabled;
data.allow_websocket_upgrade = !!data.allow_websocket_upgrade;
if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') { if (typeof data.ssl_forced !== 'undefined' && data.ssl_forced === '1') {
data.ssl_forced = true; data.ssl_forced = true;

View File

@ -98,7 +98,8 @@
"delete-confirm": "Are you sure you want to delete the Proxy host for: <strong>{domains}</strong>?", "delete-confirm": "Are you sure you want to delete the Proxy host for: <strong>{domains}</strong>?",
"help-title": "What is a Proxy Host?", "help-title": "What is a Proxy Host?",
"help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.", "help-content": "A Proxy Host is the incoming endpoint for a web service that you want to forward.\nIt provides optional SSL termination for your service that might not have SSL support built in.\nProxy Hosts are the most common use for the Nginx Proxy Manager.",
"access-list": "Access List" "access-list": "Access List",
"allow-websocket-upgrade": "Allow Websocket HTTP Upgrades"
}, },
"redirection-hosts": { "redirection-hosts": {
"title": "Redirection Hosts", "title": "Redirection Hosts",

View File

@ -17,6 +17,7 @@ const model = Backbone.Model.extend({
certificate_id: 0, certificate_id: 0,
ssl_forced: false, ssl_forced: false,
caching_enabled: false, caching_enabled: false,
allow_websocket_upgrade: false,
block_exploits: false, block_exploits: false,
advanced_config: '', advanced_config: '',
meta: {}, meta: {},