Skip to content

Commit b4393ff

Browse files
committed
feat(nginx): customisable paths & program name
no issue - Respect environment variables that customise where nginx lives and what it is called - Use env vars, not config, because this will be system-wide - Allows CLI to work with "flavours" of nginx, like OpenResty
1 parent 3bf34ad commit b4393ff

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

extensions/nginx/acme.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const download = require('download');
77

88
const {errors: {CliError, ProcessError, SystemError}} = require('../../lib');
99

10+
const nginxProgramName = process.env.NGINX_PROGRAM_NAME || 'nginx';
11+
1012
function isInstalled() {
1113
return fs.existsSync('/etc/letsencrypt/acme.sh');
1214
}
@@ -67,7 +69,7 @@ function install(ui, task) {
6769

6870
function generateCert(ui, domain, webroot, email, staging) {
6971
const cmd = `/etc/letsencrypt/acme.sh --issue --home /etc/letsencrypt --domain ${domain} --webroot ${webroot} ` +
70-
`--reloadcmd "nginx -s reload" --accountemail ${email}${staging ? ' --staging' : ''}`;
72+
`--reloadcmd "${nginxProgramName} -s reload" --accountemail ${email}${staging ? ' --staging' : ''}`;
7173

7274
return ui.sudo(cmd).catch((error) => {
7375
if (error.code === 2) {

extensions/nginx/index.js

+24-21
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ const template = require('lodash/template');
1313
const {Extension, errors} = require('../../lib');
1414
const {CliError, ProcessError} = errors;
1515

16+
const nginxConfigPath = process.env.NGINX_CONFIG_PATH || '/etc/nginx';
17+
const nginxProgramName = process.env.NGINX_PROGRAM_NAME || 'nginx';
18+
1619
class NginxExtension extends Extension {
1720
migrations() {
1821
const migrations = require('./migrations');
@@ -47,7 +50,7 @@ class NginxExtension extends Extension {
4750

4851
const confFile = `${hostname}.conf`;
4952

50-
if (fs.existsSync(`/etc/nginx/sites-available/${confFile}`)) {
53+
if (fs.existsSync(`${nginxConfigPath}/sites-available/${confFile}`)) {
5154
return 'Nginx configuration already found for this url. Skipping Nginx setup.';
5255
}
5356

@@ -74,15 +77,15 @@ class NginxExtension extends Extension {
7477
return 'SSL certs cannot be generated for IP addresses, skipping';
7578
}
7679

77-
if (fs.existsSync(`/etc/nginx/sites-available/${confFile}`)) {
80+
if (fs.existsSync(`${nginxConfigPath}/sites-available/${confFile}`)) {
7881
return 'SSL has already been set up, skipping';
7982
}
8083

8184
if (!argv.prompt && !argv.sslemail) {
8285
return 'SSL email must be provided via the --sslemail option, skipping SSL setup';
8386
}
8487

85-
if (!fs.existsSync(`/etc/nginx/sites-available/${hostname}.conf`)) {
88+
if (!fs.existsSync(`${nginxConfigPath}/sites-available/${hostname}.conf`)) {
8689
return single ? 'Nginx config file does not exist, skipping SSL setup' : true;
8790
}
8891

@@ -105,8 +108,8 @@ class NginxExtension extends Extension {
105108
port: instance.config.get('server.port')
106109
});
107110

108-
return this.template(instance, generatedConfig, 'nginx config', confFile, '/etc/nginx/sites-available').then(
109-
() => this.ui.sudo(`ln -sf /etc/nginx/sites-available/${confFile} /etc/nginx/sites-enabled/${confFile}`)
111+
return this.template(instance, generatedConfig, 'nginx config', confFile, `${nginxConfigPath}/sites-available`).then(
112+
() => this.ui.sudo(`ln -sf ${nginxConfigPath}/sites-available/${confFile} ${nginxConfigPath}/sites-enabled/${confFile}`)
110113
).then(
111114
() => this.restartNginx()
112115
).catch((error) => {
@@ -126,8 +129,8 @@ class NginxExtension extends Extension {
126129
const acme = require('./acme');
127130

128131
const rootPath = path.resolve(instance.dir, 'system', 'nginx-root');
129-
const dhparamFile = '/etc/nginx/snippets/dhparam.pem';
130-
const sslParamsFile = '/etc/nginx/snippets/ssl-params.conf';
132+
const dhparamFile = `${nginxConfigPath}/snippets/dhparam.pem`;
133+
const sslParamsFile = `${nginxConfigPath}/snippets/ssl-params.conf`;
131134
const sslParamsConf = template(fs.readFileSync(path.join(__dirname, 'templates', 'ssl-params.conf'), 'utf8'));
132135

133136
return this.ui.listr([{
@@ -210,8 +213,8 @@ class NginxExtension extends Extension {
210213
port: instance.config.get('server.port')
211214
});
212215

213-
return this.template(instance, generatedSslConfig, 'ssl config', confFile, '/etc/nginx/sites-available').then(
214-
() => this.ui.sudo(`ln -sf /etc/nginx/sites-available/${confFile} /etc/nginx/sites-enabled/${confFile}`)
216+
return this.template(instance, generatedSslConfig, 'ssl config', confFile, `${nginxConfigPath}/sites-available`).then(
217+
() => this.ui.sudo(`ln -sf ${nginxConfigPath}/sites-available/${confFile} ${nginxConfigPath}/sites-enabled/${confFile}`)
215218
).catch(error => Promise.reject(new ProcessError(error)));
216219
}
217220
}, {
@@ -233,29 +236,29 @@ class NginxExtension extends Extension {
233236

234237
const promises = [];
235238

236-
if (fs.existsSync(`/etc/nginx/sites-available/${confFile}`)) {
239+
if (fs.existsSync(`${nginxConfigPath}/sites-available/${confFile}`)) {
237240
// Nginx config exists, remove it
238241
promises.push(
239242
Promise.all([
240-
this.ui.sudo(`rm -f /etc/nginx/sites-available/${confFile}`),
241-
this.ui.sudo(`rm -f /etc/nginx/sites-enabled/${confFile}`)
243+
this.ui.sudo(`rm -f ${nginxConfigPath}/sites-available/${confFile}`),
244+
this.ui.sudo(`rm -f ${nginxConfigPath}/sites-enabled/${confFile}`)
242245
]).catch(error => Promise.reject(new CliError({
243-
message: `Nginx config file link could not be removed, you will need to do this manually for /etc/nginx/sites-available/${confFile}.`,
244-
help: `Try running 'rm -f /etc/nginx/sites-available/${confFile} && rm -f /etc/nginx/sites-enabled/${confFile}'`,
246+
message: `Nginx config file link could not be removed, you will need to do this manually for ${nginxConfigPath}/sites-available/${confFile}.`,
247+
help: `Try running 'rm -f ${nginxConfigPath}/sites-available/${confFile} && rm -f ${nginxConfigPath}/sites-enabled/${confFile}'`,
245248
err: error
246249
})))
247250
);
248251
}
249252

250-
if (fs.existsSync(`/etc/nginx/sites-available/${sslConfFile}`)) {
253+
if (fs.existsSync(`${nginxConfigPath}/sites-available/${sslConfFile}`)) {
251254
// SSL config exists, remove it
252255
promises.push(
253256
Promise.all([
254-
this.ui.sudo(`rm -f /etc/nginx/sites-available/${sslConfFile}`),
255-
this.ui.sudo(`rm -f /etc/nginx/sites-enabled/${sslConfFile}`)
257+
this.ui.sudo(`rm -f ${nginxConfigPath}/sites-available/${sslConfFile}`),
258+
this.ui.sudo(`rm -f ${nginxConfigPath}/sites-enabled/${sslConfFile}`)
256259
]).catch(error => Promise.reject(new CliError({
257-
message: `SSL config file link could not be removed, you will need to do this manually for /etc/nginx/sites-available/${sslConfFile}.`,
258-
help: `Try running 'rm -f /etc/nginx/sites-available/${sslConfFile} && rm -f /etc/nginx/sites-enabled/${sslConfFile}'`,
260+
message: `SSL config file link could not be removed, you will need to do this manually for ${nginxConfigPath}/sites-available/${sslConfFile}.`,
261+
help: `Try running 'rm -f ${nginxConfigPath}/sites-available/${sslConfFile} && rm -f ${nginxConfigPath}/sites-enabled/${sslConfFile}'`,
259262
err: error
260263
})))
261264
);
@@ -269,7 +272,7 @@ class NginxExtension extends Extension {
269272
}
270273

271274
restartNginx() {
272-
return this.ui.sudo('nginx -s reload')
275+
return this.ui.sudo(`${nginxProgramName} -s reload`)
273276
.catch(error => Promise.reject(new CliError({
274277
message: 'Failed to restart Nginx.',
275278
err: error
@@ -278,7 +281,7 @@ class NginxExtension extends Extension {
278281

279282
isSupported() {
280283
try {
281-
execa.shellSync('dpkg -l | grep nginx', {stdio: 'ignore'});
284+
execa.shellSync(`dpkg -l | grep ${nginxProgramName}`, {stdio: 'ignore'});
282285
return true;
283286
} catch (e) {
284287
return false;

lib/commands/doctor/checks/system-stack.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ const errors = require('../../../errors');
66

77
const taskTitle = 'Checking operating system compatibility';
88

9+
const nginxProgramName = process.env.NGINX_PROGRAM_NAME || 'nginx';
10+
911
function systemStack(ctx, task) {
1012
let promise;
1113

@@ -25,9 +27,9 @@ function systemStack(ctx, task) {
2527
task: () => execa.shell('dpkg -l | grep systemd')
2628
.catch(() => Promise.reject({missing: 'systemd'}))
2729
}, {
28-
title: 'Checking nginx is installed',
29-
task: () => execa.shell('dpkg -l | grep nginx')
30-
.catch(() => Promise.reject({missing: 'nginx'}))
30+
title: `Checking ${nginxProgramName} is installed`,
31+
task: () => execa.shell(`dpkg -l | grep ${nginxProgramName}`)
32+
.catch(() => Promise.reject({missing: nginxProgramName}))
3133
}], ctx, {
3234
concurrent: true,
3335
exitOnError: false,

0 commit comments

Comments
 (0)