Skip to content

Commit e1bcef6

Browse files
authored
Merge pull request #2749 from NginxProxyManager/develop
v2.10.0
2 parents 2926844 + 81f51f9 commit e1bcef6

37 files changed

+971
-896
lines changed

.version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.9.22
1+
2.10.0

Jenkinsfile

+6-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ pipeline {
1414
ansiColor('xterm')
1515
}
1616
environment {
17-
IMAGE = "nginx-proxy-manager"
17+
IMAGE = 'nginx-proxy-manager'
1818
BUILD_VERSION = getVersion()
19-
MAJOR_VERSION = "2"
19+
MAJOR_VERSION = '2'
2020
BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}"
2121
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}"
2222
COMPOSE_FILE = 'docker/docker-compose.ci.yml'
@@ -102,8 +102,8 @@ pipeline {
102102
always {
103103
// Dumps to analyze later
104104
sh 'mkdir -p debug'
105-
sh 'docker-compose logs fullstack-sqlite | gzip > debug/docker_fullstack_sqlite.log.gz'
106-
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
105+
sh 'docker-compose logs fullstack-sqlite > debug/docker_fullstack_sqlite.log'
106+
sh 'docker-compose logs db > debug/docker_db.log'
107107
// Cypress videos and screenshot artifacts
108108
dir(path: 'test/results') {
109109
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
@@ -128,8 +128,8 @@ pipeline {
128128
always {
129129
// Dumps to analyze later
130130
sh 'mkdir -p debug'
131-
sh 'docker-compose logs fullstack-mysql | gzip > debug/docker_fullstack_mysql.log.gz'
132-
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
131+
sh 'docker-compose logs fullstack-mysql > debug/docker_fullstack_mysql.log'
132+
sh 'docker-compose logs db > debug/docker_db.log'
133133
// Cypress videos and screenshot artifacts
134134
dir(path: 'test/results') {
135135
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<p align="center">
22
<img src="https://nginxproxymanager.com/github.png">
33
<br><br>
4-
<img src="https://img.shields.io/badge/version-2.9.22-green.svg?style=for-the-badge">
4+
<img src="https://img.shields.io/badge/version-2.10.0-green.svg?style=for-the-badge">
55
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
66
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
77
</a>
@@ -56,7 +56,7 @@ I won't go in to too much detail here but here are the basics for someone new to
5656
2. Create a docker-compose.yml file similar to this:
5757

5858
```yml
59-
version: '3'
59+
version: '3.8'
6060
services:
6161
app:
6262
image: 'jc21/nginx-proxy-manager:latest'
@@ -70,6 +70,8 @@ services:
7070
- ./letsencrypt:/etc/letsencrypt
7171
```
7272
73+
This is the bare minimum configuration required. See the [documentation](https://nginxproxymanager.com/setup/) for more.
74+
7375
3. Bring up your stack by running
7476
7577
```bash

backend/app.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const express = require('express');
22
const bodyParser = require('body-parser');
33
const fileUpload = require('express-fileupload');
44
const compression = require('compression');
5+
const config = require('./lib/config');
56
const log = require('./logger').express;
67

78
/**
@@ -24,7 +25,7 @@ app.enable('trust proxy', ['loopback', 'linklocal', 'uniquelocal']);
2425
app.enable('strict routing');
2526

2627
// pretty print JSON when not live
27-
if (process.env.NODE_ENV !== 'production') {
28+
if (config.debug()) {
2829
app.set('json spaces', 2);
2930
}
3031

@@ -65,7 +66,7 @@ app.use(function (err, req, res, next) {
6566
}
6667
};
6768

68-
if (process.env.NODE_ENV === 'development' || (req.baseUrl + req.path).includes('nginx/certificates')) {
69+
if (config.debug() || (req.baseUrl + req.path).includes('nginx/certificates')) {
6970
payload.debug = {
7071
stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null,
7172
previous: err.previous
@@ -74,7 +75,7 @@ app.use(function (err, req, res, next) {
7475

7576
// Not every error is worth logging - but this is good for now until it gets annoying.
7677
if (typeof err.stack !== 'undefined' && err.stack) {
77-
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
78+
if (config.debug()) {
7879
log.debug(err.stack);
7980
} else if (typeof err.public == 'undefined' || !err.public) {
8081
log.warn(err.message);

backend/db.js

+20-26
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
1-
const config = require('config');
1+
const config = require('./lib/config');
22

33
if (!config.has('database')) {
4-
throw new Error('Database config does not exist! Please read the instructions: https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md');
4+
throw new Error('Database config does not exist! Please read the instructions: https://nginxproxymanager.com/setup/');
55
}
66

77
function generateDbConfig() {
8-
if (config.database.engine === 'knex-native') {
9-
return config.database.knex;
10-
} else
11-
return {
12-
client: config.database.engine,
13-
connection: {
14-
host: config.database.host,
15-
user: config.database.user,
16-
password: config.database.password,
17-
database: config.database.name,
18-
port: config.database.port
19-
},
20-
migrations: {
21-
tableName: 'migrations'
22-
}
23-
};
8+
const cfg = config.get('database');
9+
if (cfg.engine === 'knex-native') {
10+
return cfg.knex;
11+
}
12+
return {
13+
client: cfg.engine,
14+
connection: {
15+
host: cfg.host,
16+
user: cfg.user,
17+
password: cfg.password,
18+
database: cfg.name,
19+
port: cfg.port
20+
},
21+
migrations: {
22+
tableName: 'migrations'
23+
}
24+
};
2425
}
2526

26-
27-
let data = generateDbConfig();
28-
29-
if (typeof config.database.version !== 'undefined') {
30-
data.version = config.database.version;
31-
}
32-
33-
module.exports = require('knex')(data);
27+
module.exports = require('knex')(generateDbConfig());

backend/index.js

-87
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
const logger = require('./logger').global;
44

55
async function appStart () {
6-
// Create config file db settings if environment variables have been set
7-
await createDbConfigFromEnvironment();
8-
96
const migrate = require('./migrate');
107
const setup = require('./setup');
118
const app = require('./app');
@@ -42,90 +39,6 @@ async function appStart () {
4239
});
4340
}
4441

45-
async function createDbConfigFromEnvironment() {
46-
return new Promise((resolve, reject) => {
47-
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
48-
const envMysqlPort = process.env.DB_MYSQL_PORT || null;
49-
const envMysqlUser = process.env.DB_MYSQL_USER || null;
50-
const envMysqlName = process.env.DB_MYSQL_NAME || null;
51-
let envSqliteFile = process.env.DB_SQLITE_FILE || null;
52-
53-
const fs = require('fs');
54-
const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json';
55-
let configData = {};
56-
57-
try {
58-
configData = require(filename);
59-
} catch (err) {
60-
// do nothing
61-
}
62-
63-
if (configData.database && configData.database.engine && !configData.database.fromEnv) {
64-
logger.info('Manual db configuration already exists, skipping config creation from environment variables');
65-
resolve();
66-
return;
67-
}
68-
69-
if ((!envMysqlHost || !envMysqlPort || !envMysqlUser || !envMysqlName) && !envSqliteFile){
70-
envSqliteFile = '/data/database.sqlite';
71-
logger.info(`No valid environment variables for database provided, using default SQLite file '${envSqliteFile}'`);
72-
}
73-
74-
if (envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) {
75-
const newConfig = {
76-
fromEnv: true,
77-
engine: 'mysql',
78-
host: envMysqlHost,
79-
port: envMysqlPort,
80-
user: envMysqlUser,
81-
password: process.env.DB_MYSQL_PASSWORD,
82-
name: envMysqlName,
83-
};
84-
85-
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
86-
// Config is unchanged, skip overwrite
87-
resolve();
88-
return;
89-
}
90-
91-
logger.info('Generating MySQL knex configuration from environment variables');
92-
configData.database = newConfig;
93-
94-
} else {
95-
const newConfig = {
96-
fromEnv: true,
97-
engine: 'knex-native',
98-
knex: {
99-
client: 'sqlite3',
100-
connection: {
101-
filename: envSqliteFile
102-
},
103-
useNullAsDefault: true
104-
}
105-
};
106-
if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) {
107-
// Config is unchanged, skip overwrite
108-
resolve();
109-
return;
110-
}
111-
112-
logger.info('Generating SQLite knex configuration');
113-
configData.database = newConfig;
114-
}
115-
116-
// Write config
117-
fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => {
118-
if (err) {
119-
logger.error('Could not write db config to config file: ' + filename);
120-
reject(err);
121-
} else {
122-
logger.debug('Wrote db configuration to config file: ' + filename);
123-
resolve();
124-
}
125-
});
126-
});
127-
}
128-
12942
try {
13043
appStart();
13144
} catch (err) {

backend/internal/certificate.js

+30-18
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
1-
const _ = require('lodash');
2-
const fs = require('fs');
3-
const https = require('https');
4-
const tempWrite = require('temp-write');
5-
const moment = require('moment');
6-
const logger = require('../logger').ssl;
7-
const error = require('../lib/error');
8-
const utils = require('../lib/utils');
9-
const certificateModel = require('../models/certificate');
10-
const dnsPlugins = require('../global/certbot-dns-plugins');
11-
const internalAuditLog = require('./audit-log');
12-
const internalNginx = require('./nginx');
13-
const internalHost = require('./host');
14-
const letsencryptStaging = process.env.NODE_ENV !== 'production';
1+
const _ = require('lodash');
2+
const fs = require('fs');
3+
const https = require('https');
4+
const tempWrite = require('temp-write');
5+
const moment = require('moment');
6+
const logger = require('../logger').ssl;
7+
const config = require('../lib/config');
8+
const error = require('../lib/error');
9+
const utils = require('../lib/utils');
10+
const certificateModel = require('../models/certificate');
11+
const dnsPlugins = require('../global/certbot-dns-plugins');
12+
const internalAuditLog = require('./audit-log');
13+
const internalNginx = require('./nginx');
14+
const internalHost = require('./host');
15+
const archiver = require('archiver');
16+
const path = require('path');
17+
const { isArray } = require('lodash');
18+
19+
const letsencryptStaging = config.useLetsencryptStaging();
1520
const letsencryptConfig = '/etc/letsencrypt.ini';
1621
const certbotCommand = 'certbot';
17-
const archiver = require('archiver');
18-
const path = require('path');
19-
const { isArray } = require('lodash');
2022

2123
function omissions() {
2224
return ['is_deleted'];
@@ -46,6 +48,8 @@ const internalCertificate = {
4648

4749
const cmd = certbotCommand + ' renew --non-interactive --quiet ' +
4850
'--config "' + letsencryptConfig + '" ' +
51+
'--work-dir "/tmp/letsencrypt-lib" ' +
52+
'--logs-dir "/tmp/letsencrypt-log" ' +
4953
'--preferred-challenges "dns,http" ' +
5054
'--disable-hook-validation ' +
5155
(letsencryptStaging ? '--staging' : '');
@@ -833,6 +837,8 @@ const internalCertificate = {
833837

834838
const cmd = certbotCommand + ' certonly ' +
835839
'--config "' + letsencryptConfig + '" ' +
840+
'--work-dir "/tmp/letsencrypt-lib" ' +
841+
'--logs-dir "/tmp/letsencrypt-log" ' +
836842
'--cert-name "npm-' + certificate.id + '" ' +
837843
'--agree-tos ' +
838844
'--authenticator webroot ' +
@@ -871,13 +877,15 @@ const internalCertificate = {
871877
const escapedCredentials = certificate.meta.dns_provider_credentials.replaceAll('\'', '\\\'').replaceAll('\\', '\\\\');
872878
const credentialsCmd = 'mkdir -p /etc/letsencrypt/credentials 2> /dev/null; echo \'' + escapedCredentials + '\' > \'' + credentialsLocation + '\' && chmod 600 \'' + credentialsLocation + '\'';
873879
// we call `. /opt/certbot/bin/activate` (`.` is alternative to `source` in dash) to access certbot venv
874-
let prepareCmd = '. /opt/certbot/bin/activate && pip install ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies + ' && deactivate';
880+
const prepareCmd = '. /opt/certbot/bin/activate && pip install --no-cache-dir --user ' + dns_plugin.package_name + (dns_plugin.version_requirement || '') + ' ' + dns_plugin.dependencies + ' && deactivate';
875881

876882
// Whether the plugin has a --<name>-credentials argument
877883
const hasConfigArg = certificate.meta.dns_provider !== 'route53';
878884

879885
let mainCmd = certbotCommand + ' certonly ' +
880886
'--config "' + letsencryptConfig + '" ' +
887+
'--work-dir "/tmp/letsencrypt-lib" ' +
888+
'--logs-dir "/tmp/letsencrypt-log" ' +
881889
'--cert-name "npm-' + certificate.id + '" ' +
882890
'--agree-tos ' +
883891
'--email "' + certificate.meta.letsencrypt_email + '" ' +
@@ -974,6 +982,8 @@ const internalCertificate = {
974982

975983
const cmd = certbotCommand + ' renew --force-renewal ' +
976984
'--config "' + letsencryptConfig + '" ' +
985+
'--work-dir "/tmp/letsencrypt-lib" ' +
986+
'--logs-dir "/tmp/letsencrypt-log" ' +
977987
'--cert-name "npm-' + certificate.id + '" ' +
978988
'--preferred-challenges "dns,http" ' +
979989
'--no-random-sleep-on-renew ' +
@@ -1004,6 +1014,8 @@ const internalCertificate = {
10041014

10051015
let mainCmd = certbotCommand + ' renew ' +
10061016
'--config "' + letsencryptConfig + '" ' +
1017+
'--work-dir "/tmp/letsencrypt-lib" ' +
1018+
'--logs-dir "/tmp/letsencrypt-log" ' +
10071019
'--cert-name "npm-' + certificate.id + '" ' +
10081020
'--disable-hook-validation ' +
10091021
'--no-random-sleep-on-renew ' +

0 commit comments

Comments
 (0)