Skip to content

Commit 70a445e

Browse files
authored
Merge pull request NginxProxyManager#704 from chaptergy/allow-setup-without-config-file
Removes the need of a config file and allows db config via environment
2 parents 2115da2 + 1337c50 commit 70a445e

File tree

7 files changed

+173
-101
lines changed

7 files changed

+173
-101
lines changed

.jenkins/config-mysql.json

Lines changed: 0 additions & 10 deletions
This file was deleted.

.jenkins/config-sqlite.json

Lines changed: 0 additions & 11 deletions
This file was deleted.

backend/index.js

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22

33
const logger = require('./logger').global;
44

5-
function appStart () {
5+
async function appStart () {
6+
// Create config file db settings if environment variables have been set
7+
await createDbConfigFromEnvironment();
8+
69
const migrate = require('./migrate');
710
const setup = require('./setup');
811
const app = require('./app');
912
const apiValidator = require('./lib/validator/api');
1013
const internalCertificate = require('./internal/certificate');
1114
const internalIpRanges = require('./internal/ip_ranges');
1215

16+
1317
return migrate.latest()
1418
.then(setup)
1519
.then(() => {
@@ -39,6 +43,87 @@ function appStart () {
3943
});
4044
}
4145

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

docker/docker-compose.ci.yml

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ services:
55
fullstack-mysql:
66
image: ${IMAGE}:ci-${BUILD_NUMBER}
77
environment:
8-
- NODE_ENV=development
9-
- FORCE_COLOR=1
8+
NODE_ENV: "development"
9+
FORCE_COLOR: 1
10+
DB_MYSQL_HOST: "db"
11+
DB_MYSQL_PORT: 3306
12+
DB_MYSQL_USER: "npm"
13+
DB_MYSQL_PASSWORD: "npm"
14+
DB_MYSQL_NAME: "npm"
1015
volumes:
1116
- npm_data:/data
12-
- ../.jenkins/config-mysql.json:/app/config/development.json
1317
expose:
1418
- 81
1519
- 80
@@ -20,11 +24,11 @@ services:
2024
fullstack-sqlite:
2125
image: ${IMAGE}:ci-${BUILD_NUMBER}
2226
environment:
23-
- NODE_ENV=development
24-
- FORCE_COLOR=1
27+
NODE_ENV: "development"
28+
FORCE_COLOR: 1
29+
DB_SQLITE_FILE: "/data/database.sqlite"
2530
volumes:
2631
- npm_data:/data
27-
- ../.jenkins/config-sqlite.json:/app/config/development.json
2832
expose:
2933
- 81
3034
- 80

docker/docker-compose.dev.yml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@ services:
1414
networks:
1515
- nginx_proxy_manager
1616
environment:
17-
- NODE_ENV=development
18-
- FORCE_COLOR=1
19-
- DEVELOPMENT=true
20-
#- DISABLE_IPV6=true
17+
NODE_ENV: "development"
18+
FORCE_COLOR: 1
19+
DEVELOPMENT: "true"
20+
DB_MYSQL_HOST: "db"
21+
DB_MYSQL_PORT: 3306
22+
DB_MYSQL_USER: "npm"
23+
DB_MYSQL_PASSWORD: "npm"
24+
DB_MYSQL_NAME: "npm"
25+
# DB_SQLITE_FILE: "/data/database.sqlite"
26+
# DISABLE_IPV6: "true"
2127
volumes:
2228
- npm_data:/data
2329
- le_data:/etc/letsencrypt

docs/README.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,7 @@ footer: MIT Licensed | Copyright © 2016-present jc21.com
4545
- [Docker Install documentation](https://docs.docker.com/install/)
4646
- [Docker-Compose Install documentation](https://docs.docker.com/compose/install/)
4747

48-
2. Create a config file for example
49-
```json
50-
{
51-
"database": {
52-
"engine": "mysql",
53-
"host": "db",
54-
"name": "npm",
55-
"user": "npm",
56-
"password": "npm",
57-
"port": 3306
58-
}
59-
}
60-
```
61-
62-
3. Create a docker-compose.yml file similar to this:
48+
2. Create a docker-compose.yml file similar to this:
6349

6450
```yml
6551
version: '3'
@@ -70,8 +56,13 @@ services:
7056
- '80:80'
7157
- '81:81'
7258
- '443:443'
59+
environment:
60+
DB_MYSQL_HOST: "db"
61+
DB_MYSQL_PORT: 3306
62+
DB_MYSQL_USER: "npm"
63+
DB_MYSQL_PASSWORD: "npm"
64+
DB_MYSQL_NAME: "npm"
7365
volumes:
74-
- ./config.json:/app/config/production.json
7566
- ./data:/data
7667
- ./letsencrypt:/etc/letsencrypt
7768
db:
@@ -85,13 +76,13 @@ services:
8576
- ./data/mysql:/var/lib/mysql
8677
```
8778
88-
4. Bring up your stack
79+
3. Bring up your stack
8980
9081
```bash
9182
docker-compose up -d
9283
```
9384

94-
5. Log in to the Admin UI
85+
4. Log in to the Admin UI
9586

9687
When your docker container is running, connect to it on port `81` for the admin interface.
9788
Sometimes this can take a little bit because of the entropy of keys.

docs/setup/README.md

Lines changed: 58 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,5 @@
11
# Full Setup Instructions
22

3-
### Configuration File
4-
5-
**The configuration file needs to be provided by you!**
6-
7-
Don't worry, this is easy to do.
8-
9-
The app requires a configuration file to let it know what database you're using. By default, this file is called `config.json`
10-
11-
Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below:
12-
13-
```json
14-
{
15-
"database": {
16-
"engine": "mysql",
17-
"host": "db",
18-
"name": "npm",
19-
"user": "npm",
20-
"password": "npm",
21-
"port": 3306
22-
}
23-
}
24-
```
25-
26-
Alternatively if you would like to use a Sqlite database file:
27-
28-
```json
29-
{
30-
"database": {
31-
"engine": "knex-native",
32-
"knex": {
33-
"client": "sqlite3",
34-
"connection": {
35-
"filename": "/data/database.sqlite"
36-
}
37-
}
38-
}
39-
}
40-
```
41-
42-
Once you've created your configuration file it's easy to mount it in the docker container.
43-
44-
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation. These keys
45-
affect the login and session management of the application. If these keys change for any reason, all users will be logged out.
46-
47-
483
### MySQL Database
494

505
If you opt for the MySQL configuration you will have to provide the database server yourself. You can also use MariaDB. Here are the minimum supported versions:
@@ -61,7 +16,6 @@ When using a `mariadb` database, the NPM configuration file should still use the
6116

6217
:::
6318

64-
6519
### Running the App
6620

6721
Via `docker-compose`:
@@ -70,7 +24,7 @@ Via `docker-compose`:
7024
version: "3"
7125
services:
7226
app:
73-
image: jc21/nginx-proxy-manager:2
27+
image: 'jc21/nginx-proxy-manager:latest'
7428
restart: always
7529
ports:
7630
# Public HTTP Port:
@@ -80,11 +34,18 @@ services:
8034
# Admin Web Port:
8135
- '81:81'
8236
environment:
37+
# These are the settings to access your db
38+
DB_MYSQL_HOST: "db"
39+
DB_MYSQL_PORT: 3306
40+
DB_MYSQL_USER: "npm"
41+
DB_MYSQL_PASSWORD: "npm"
42+
DB_MYSQL_NAME: "npm"
43+
# If you would rather use Sqlite uncomment this
44+
# and remove all DB_MYSQL_* lines above
45+
# DB_SQLITE_FILE: "/data/database.sqlite"
8346
# Uncomment this if IPv6 is not enabled on your host
8447
# DISABLE_IPV6: 'true'
8548
volumes:
86-
# Make sure this config.json file exists as per instructions above:
87-
- ./config.json:/app/config/production.json
8849
- ./data:/data
8950
- ./letsencrypt:/etc/letsencrypt
9051
depends_on:
@@ -101,14 +62,14 @@ services:
10162
- ./data/mysql:/var/lib/mysql
10263
```
10364
65+
_Please note, that `DB_MYSQL_*` environment variables will take precedent over `DB_SQLITE_*` variables. So if you keep the MySQL variables, you will not be able to use Sqlite._
66+
10467
Then:
10568

10669
```bash
10770
docker-compose up -d
10871
```
10972

110-
The config file (config.json) must be present in this directory.
111-
11273
### Running on Raspberry PI / ARM devices
11374

11475
The docker images support the following architectures:
@@ -146,3 +107,49 @@ Password: changeme
146107
```
147108
148109
Immediately after logging in with this default user you will be asked to modify your details and change your password.
110+
111+
### Configuration File
112+
113+
::: warning
114+
115+
This section is meant for advanced users
116+
117+
:::
118+
119+
If you would like more control over the database settings you can define a custom config JSON file.
120+
121+
122+
Here's an example for `sqlite` configuration as it is generated from the environment variables:
123+
124+
```json
125+
{
126+
"database": {
127+
"engine": "knex-native",
128+
"knex": {
129+
"client": "sqlite3",
130+
"connection": {
131+
"filename": "/data/database.sqlite"
132+
}
133+
}
134+
}
135+
}
136+
```
137+
138+
You can modify the `knex` object with your custom configuration, but note that not all knex clients might be installed in the image.
139+
140+
Once you've created your configuration file you can mount it to `/app/config/production.json` inside you container using:
141+
142+
```
143+
[...]
144+
services:
145+
app:
146+
image: 'jc21/nginx-proxy-manager:latest'
147+
[...]
148+
volumes:
149+
- ./config.json:/app/config/production.json
150+
[...]
151+
[...]
152+
```
153+
154+
**Note:** After the first run of the application, the config file will be altered to include generated encryption keys unique to your installation.
155+
These keys affect the login and session management of the application. If these keys change for any reason, all users will be logged out.

0 commit comments

Comments
 (0)