mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-31 15:53:33 +00:00 
			
		
		
		
	Removes the need of a config file and allows db config via environment
This commit is contained in:
		| @@ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
| 	"database": { |  | ||||||
| 		"engine": "mysql", |  | ||||||
| 		"host": "db", |  | ||||||
| 		"name": "npm", |  | ||||||
| 		"user": "npm", |  | ||||||
| 		"password": "npm", |  | ||||||
| 		"port": 3306 |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| { |  | ||||||
| 	"database": { |  | ||||||
| 		"engine": "knex-native", |  | ||||||
| 		"knex": { |  | ||||||
| 			"client": "sqlite3", |  | ||||||
| 			"connection": { |  | ||||||
| 				"filename": "/data/database.sqlite" |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| @@ -2,7 +2,10 @@ | |||||||
|  |  | ||||||
| const logger = require('./logger').global; | const logger = require('./logger').global; | ||||||
|  |  | ||||||
| function appStart () { | async function appStart () { | ||||||
|  | 	// Create config file db settings if environment variables have been set | ||||||
|  | 	await createDbConfigFromEnvironment(); | ||||||
|  |  | ||||||
| 	const migrate             = require('./migrate'); | 	const migrate             = require('./migrate'); | ||||||
| 	const setup               = require('./setup'); | 	const setup               = require('./setup'); | ||||||
| 	const app                 = require('./app'); | 	const app                 = require('./app'); | ||||||
| @@ -10,6 +13,7 @@ function appStart () { | |||||||
| 	const internalCertificate = require('./internal/certificate'); | 	const internalCertificate = require('./internal/certificate'); | ||||||
| 	const internalIpRanges    = require('./internal/ip_ranges'); | 	const internalIpRanges    = require('./internal/ip_ranges'); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	return migrate.latest() | 	return migrate.latest() | ||||||
| 		.then(setup) | 		.then(setup) | ||||||
| 		.then(() => { | 		.then(() => { | ||||||
| @@ -39,6 +43,87 @@ function appStart () { | |||||||
| 		}); | 		}); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | async function createDbConfigFromEnvironment(){ | ||||||
|  | 	return new Promise((resolve, reject) => { | ||||||
|  | 		const envMysqlHost  = process.env.DB_MYSQL_HOST; | ||||||
|  | 		const envMysqlPort  = process.env.DB_MYSQL_PORT; | ||||||
|  | 		const envMysqlUser  = process.env.DB_MYSQL_USER; | ||||||
|  | 		const envMysqlName  = process.env.DB_MYSQL_NAME; | ||||||
|  | 		const envSqliteFile = process.env.DB_SQLITE_FILE; | ||||||
|  | 		if ((envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) || envSqliteFile) { | ||||||
|  | 			const fs       = require('fs'); | ||||||
|  | 			const filename = (process.env.NODE_CONFIG_DIR || './config') + '/' + (process.env.NODE_ENV || 'default') + '.json'; | ||||||
|  | 			let configData = {}; | ||||||
|  |  | ||||||
|  | 			try { | ||||||
|  | 				configData = require(filename); | ||||||
|  | 			} catch (err) { | ||||||
|  | 				// do nothing | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (configData.database && configData.database.engine && !configData.database.fromEnv) { | ||||||
|  | 				logger.info('Manual db configuration already exists, skipping config creation from environment variables'); | ||||||
|  | 				resolve(); | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (envMysqlHost && envMysqlPort && envMysqlUser && envMysqlName) { | ||||||
|  | 				const newConfig = { | ||||||
|  | 					fromEnv:  true, | ||||||
|  | 					engine:   'mysql', | ||||||
|  | 					host:     envMysqlHost, | ||||||
|  | 					port:     envMysqlPort, | ||||||
|  | 					user:     envMysqlUser, | ||||||
|  | 					password: process.env.DB_MYSQL_PASSWORD, | ||||||
|  | 					name:     envMysqlName, | ||||||
|  | 				}; | ||||||
|  |  | ||||||
|  | 				if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) { | ||||||
|  | 					// Config is unchanged, skip overwrite | ||||||
|  | 					resolve(); | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				logger.info('Generating MySQL db configuration from environment variables'); | ||||||
|  | 				configData.database = newConfig; | ||||||
|  |  | ||||||
|  | 			} else { | ||||||
|  | 				const newConfig = { | ||||||
|  | 					fromEnv: true, | ||||||
|  | 					engine:  'knex-native', | ||||||
|  | 					knex:    { | ||||||
|  | 						client:     'sqlite3', | ||||||
|  | 						connection: { | ||||||
|  | 							filename: envSqliteFile | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				}; | ||||||
|  | 				if (JSON.stringify(configData.database) === JSON.stringify(newConfig)) { | ||||||
|  | 					// Config is unchanged, skip overwrite | ||||||
|  | 					resolve(); | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				logger.info('Generating Sqlite db configuration from environment variables'); | ||||||
|  | 				configData.database = newConfig; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// Write config | ||||||
|  | 			fs.writeFile(filename, JSON.stringify(configData, null, 2), (err) => { | ||||||
|  | 				if (err) { | ||||||
|  | 					logger.error('Could not write db config to config file: ' + filename); | ||||||
|  | 					reject(err); | ||||||
|  | 				} else { | ||||||
|  | 					logger.info('Wrote db configuration to config file: ' + filename); | ||||||
|  | 					resolve(); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  | 		} else { | ||||||
|  | 			// resolve(); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
| try { | try { | ||||||
| 	appStart(); | 	appStart(); | ||||||
| } catch (err) { | } catch (err) { | ||||||
|   | |||||||
| @@ -5,11 +5,15 @@ services: | |||||||
|   fullstack-mysql: |   fullstack-mysql: | ||||||
|     image: ${IMAGE}:ci-${BUILD_NUMBER} |     image: ${IMAGE}:ci-${BUILD_NUMBER} | ||||||
|     environment: |     environment: | ||||||
|       - NODE_ENV=development |       NODE_ENV: "development" | ||||||
|       - FORCE_COLOR=1 |       FORCE_COLOR: 1 | ||||||
|  |       DB_MYSQL_HOST: "db" | ||||||
|  |       DB_MYSQL_PORT: 3306 | ||||||
|  |       DB_MYSQL_USER: "npm" | ||||||
|  |       DB_MYSQL_PASSWORD: "npm" | ||||||
|  |       DB_MYSQL_NAME: "npm" | ||||||
|     volumes: |     volumes: | ||||||
|       - npm_data:/data |       - npm_data:/data | ||||||
|       - ../.jenkins/config-mysql.json:/app/config/development.json |  | ||||||
|     expose: |     expose: | ||||||
|       - 81 |       - 81 | ||||||
|       - 80 |       - 80 | ||||||
| @@ -20,8 +24,9 @@ services: | |||||||
|   fullstack-sqlite: |   fullstack-sqlite: | ||||||
|     image: ${IMAGE}:ci-${BUILD_NUMBER} |     image: ${IMAGE}:ci-${BUILD_NUMBER} | ||||||
|     environment: |     environment: | ||||||
|       - NODE_ENV=development |       NODE_ENV: "development" | ||||||
|       - FORCE_COLOR=1 |       FORCE_COLOR: 1 | ||||||
|  |       DB_SQLITE_FILE: "/data/database.sqlite" | ||||||
|     volumes: |     volumes: | ||||||
|       - npm_data:/data |       - npm_data:/data | ||||||
|       - ../.jenkins/config-sqlite.json:/app/config/development.json |       - ../.jenkins/config-sqlite.json:/app/config/development.json | ||||||
|   | |||||||
| @@ -14,10 +14,16 @@ services: | |||||||
|     networks: |     networks: | ||||||
|       - nginx_proxy_manager |       - nginx_proxy_manager | ||||||
|     environment: |     environment: | ||||||
|       - NODE_ENV=development |       NODE_ENV: "development" | ||||||
|       - FORCE_COLOR=1 |       FORCE_COLOR: 1 | ||||||
|       - DEVELOPMENT=true |       DEVELOPMENT: "true" | ||||||
|       #- DISABLE_IPV6=true |       DB_MYSQL_HOST: "db" | ||||||
|  |       DB_MYSQL_PORT: 3306 | ||||||
|  |       DB_MYSQL_USER: "npm" | ||||||
|  |       DB_MYSQL_PASSWORD: "npm" | ||||||
|  |       DB_MYSQL_NAME: "npm" | ||||||
|  |       # DB_SQLITE_FILE: "/data/database.sqlite" | ||||||
|  |       # DISABLE_IPV6: "true" | ||||||
|     volumes: |     volumes: | ||||||
|       - npm_data:/data |       - npm_data:/data | ||||||
|       - le_data:/etc/letsencrypt |       - le_data:/etc/letsencrypt | ||||||
|   | |||||||
| @@ -45,21 +45,7 @@ footer: MIT Licensed | Copyright © 2016-present jc21.com | |||||||
| - [Docker Install documentation](https://docs.docker.com/install/) | - [Docker Install documentation](https://docs.docker.com/install/) | ||||||
| - [Docker-Compose Install documentation](https://docs.docker.com/compose/install/) | - [Docker-Compose Install documentation](https://docs.docker.com/compose/install/) | ||||||
|  |  | ||||||
| 2. Create a config file for example | 2. Create a docker-compose.yml file similar to this: | ||||||
| ```json |  | ||||||
| { |  | ||||||
|   "database": { |  | ||||||
|     "engine": "mysql", |  | ||||||
|     "host": "db", |  | ||||||
|     "name": "npm", |  | ||||||
|     "user": "npm", |  | ||||||
|     "password": "npm", |  | ||||||
|     "port": 3306 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| 3. Create a docker-compose.yml file similar to this: |  | ||||||
|  |  | ||||||
| ```yml | ```yml | ||||||
| version: '3' | version: '3' | ||||||
| @@ -70,8 +56,13 @@ services: | |||||||
|       - '80:80' |       - '80:80' | ||||||
|       - '81:81' |       - '81:81' | ||||||
|       - '443:443' |       - '443:443' | ||||||
|  |     environment: | ||||||
|  |       DB_MYSQL_HOST: "db" | ||||||
|  |       DB_MYSQL_PORT: 3306 | ||||||
|  |       DB_MYSQL_USER: "npm" | ||||||
|  |       DB_MYSQL_PASSWORD: "npm" | ||||||
|  |       DB_MYSQL_NAME: "npm" | ||||||
|     volumes: |     volumes: | ||||||
|       - ./config.json:/app/config/production.json |  | ||||||
|       - ./data:/data |       - ./data:/data | ||||||
|       - ./letsencrypt:/etc/letsencrypt |       - ./letsencrypt:/etc/letsencrypt | ||||||
|   db: |   db: | ||||||
| @@ -85,13 +76,13 @@ services: | |||||||
|       - ./data/mysql:/var/lib/mysql |       - ./data/mysql:/var/lib/mysql | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 4. Bring up your stack | 3. Bring up your stack | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| docker-compose up -d | docker-compose up -d | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| 5. Log in to the Admin UI | 4. Log in to the Admin UI | ||||||
|  |  | ||||||
| When your docker container is running, connect to it on port `81` for the admin interface. | When your docker container is running, connect to it on port `81` for the admin interface. | ||||||
| Sometimes this can take a little bit because of the entropy of keys. | Sometimes this can take a little bit because of the entropy of keys. | ||||||
|   | |||||||
| @@ -1,50 +1,5 @@ | |||||||
| # Full Setup Instructions | # Full Setup Instructions | ||||||
|  |  | ||||||
| ### Configuration File |  | ||||||
|  |  | ||||||
| **The configuration file needs to be provided by you!** |  | ||||||
|  |  | ||||||
| Don't worry, this is easy to do. |  | ||||||
|  |  | ||||||
| The app requires a configuration file to let it know what database you're using. By default, this file is called `config.json` |  | ||||||
|  |  | ||||||
| Here's an example configuration for `mysql` (or mariadb) that is compatible with the docker-compose example below: |  | ||||||
|  |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
|   "database": { |  | ||||||
|     "engine": "mysql", |  | ||||||
|     "host": "db", |  | ||||||
|     "name": "npm", |  | ||||||
|     "user": "npm", |  | ||||||
|     "password": "npm", |  | ||||||
|     "port": 3306 |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Alternatively if you would like to use a Sqlite database file: |  | ||||||
|  |  | ||||||
| ```json |  | ||||||
| { |  | ||||||
|   "database": { |  | ||||||
|     "engine": "knex-native", |  | ||||||
|     "knex": { |  | ||||||
|       "client": "sqlite3", |  | ||||||
|       "connection": { |  | ||||||
|         "filename": "/data/database.sqlite" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| Once you've created your configuration file it's easy to mount it in the docker container. |  | ||||||
|  |  | ||||||
| **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 |  | ||||||
| affect the login and session management of the application. If these keys change for any reason, all users will be logged out. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ### MySQL Database | ### MySQL Database | ||||||
|  |  | ||||||
| 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: | 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 | |||||||
|  |  | ||||||
| ::: | ::: | ||||||
|  |  | ||||||
|  |  | ||||||
| ### Running the App | ### Running the App | ||||||
|  |  | ||||||
| Via `docker-compose`: | Via `docker-compose`: | ||||||
| @@ -80,11 +34,18 @@ services: | |||||||
|       # Admin Web Port: |       # Admin Web Port: | ||||||
|       - '81:81' |       - '81:81' | ||||||
|     environment: |     environment: | ||||||
|  |       # These are the settings to access your db | ||||||
|  |       DB_MYSQL_HOST: "db" | ||||||
|  |       DB_MYSQL_PORT: 3306 | ||||||
|  |       DB_MYSQL_USER: "npm" | ||||||
|  |       DB_MYSQL_PASSWORD: "npm" | ||||||
|  |       DB_MYSQL_NAME: "npm" | ||||||
|  |       # If you would rather use Sqlite uncomment this | ||||||
|  |       # and remove all DB_MYSQL_* lines above | ||||||
|  |       # DB_SQLITE_FILE: "/data/database.sqlite" | ||||||
|       # Uncomment this if IPv6 is not enabled on your host |       # Uncomment this if IPv6 is not enabled on your host | ||||||
|       # DISABLE_IPV6: 'true' |       # DISABLE_IPV6: 'true' | ||||||
|     volumes: |     volumes: | ||||||
|       # Make sure this config.json file exists as per instructions above: |  | ||||||
|       - ./config.json:/app/config/production.json |  | ||||||
|       - ./data:/data |       - ./data:/data | ||||||
|       - ./letsencrypt:/etc/letsencrypt |       - ./letsencrypt:/etc/letsencrypt | ||||||
|     depends_on: |     depends_on: | ||||||
| @@ -101,14 +62,14 @@ services: | |||||||
|       - ./data/mysql:/var/lib/mysql |       - ./data/mysql:/var/lib/mysql | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | _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._ | ||||||
|  |  | ||||||
| Then: | Then: | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| docker-compose up -d | docker-compose up -d | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| The config file (config.json) must be present in this directory. |  | ||||||
|  |  | ||||||
| ### Running on Raspberry PI / ARM devices | ### Running on Raspberry PI / ARM devices | ||||||
|  |  | ||||||
| The docker images support the following architectures: | The docker images support the following architectures: | ||||||
| @@ -146,3 +107,49 @@ Password: changeme | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| Immediately after logging in with this default user you will be asked to modify your details and change your password. | Immediately after logging in with this default user you will be asked to modify your details and change your password. | ||||||
|  |  | ||||||
|  | ### Configuration File | ||||||
|  |  | ||||||
|  | ::: warning | ||||||
|  |  | ||||||
|  | This section is meant for advanced users | ||||||
|  |  | ||||||
|  | ::: | ||||||
|  |  | ||||||
|  | If you would like more control over the database settings you can define a custom config JSON file. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Here's an example for `sqlite` configuration as it is generated from the environment variables: | ||||||
|  |  | ||||||
|  | ```json | ||||||
|  | { | ||||||
|  |   "database": { | ||||||
|  |     "engine": "knex-native", | ||||||
|  |     "knex": { | ||||||
|  |       "client": "sqlite3", | ||||||
|  |       "connection": { | ||||||
|  |         "filename": "/data/database.sqlite" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | You can modify the `knex` object with your custom configuration, but note that not all knex clients might be installed in the image. | ||||||
|  |  | ||||||
|  | Once you've created your configuration file you can mount it to `/app/config/production.json` inside you container using: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | [...] | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     image: 'jc21/nginx-proxy-manager:latest' | ||||||
|  |     [...] | ||||||
|  |     volumes: | ||||||
|  |       - ./config.json:/app/config/production.json | ||||||
|  |       [...] | ||||||
|  | [...] | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | **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 affect the login and session management of the application. If these keys change for any reason, all users will be logged out. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user