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; | ||||
|  | ||||
| function appStart () { | ||||
| async function appStart () { | ||||
| 	// Create config file db settings if environment variables have been set | ||||
| 	await createDbConfigFromEnvironment(); | ||||
|  | ||||
| 	const migrate             = require('./migrate'); | ||||
| 	const setup               = require('./setup'); | ||||
| 	const app                 = require('./app'); | ||||
| @@ -10,6 +13,7 @@ function appStart () { | ||||
| 	const internalCertificate = require('./internal/certificate'); | ||||
| 	const internalIpRanges    = require('./internal/ip_ranges'); | ||||
|  | ||||
|  | ||||
| 	return migrate.latest() | ||||
| 		.then(setup) | ||||
| 		.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 { | ||||
| 	appStart(); | ||||
| } catch (err) { | ||||
|   | ||||
| @@ -5,11 +5,15 @@ services: | ||||
|   fullstack-mysql: | ||||
|     image: ${IMAGE}:ci-${BUILD_NUMBER} | ||||
|     environment: | ||||
|       - NODE_ENV=development | ||||
|       - FORCE_COLOR=1 | ||||
|       NODE_ENV: "development" | ||||
|       FORCE_COLOR: 1 | ||||
|       DB_MYSQL_HOST: "db" | ||||
|       DB_MYSQL_PORT: 3306 | ||||
|       DB_MYSQL_USER: "npm" | ||||
|       DB_MYSQL_PASSWORD: "npm" | ||||
|       DB_MYSQL_NAME: "npm" | ||||
|     volumes: | ||||
|       - npm_data:/data | ||||
|       - ../.jenkins/config-mysql.json:/app/config/development.json | ||||
|     expose: | ||||
|       - 81 | ||||
|       - 80 | ||||
| @@ -20,8 +24,9 @@ services: | ||||
|   fullstack-sqlite: | ||||
|     image: ${IMAGE}:ci-${BUILD_NUMBER} | ||||
|     environment: | ||||
|       - NODE_ENV=development | ||||
|       - FORCE_COLOR=1 | ||||
|       NODE_ENV: "development" | ||||
|       FORCE_COLOR: 1 | ||||
|       DB_SQLITE_FILE: "/data/database.sqlite" | ||||
|     volumes: | ||||
|       - npm_data:/data | ||||
|       - ../.jenkins/config-sqlite.json:/app/config/development.json | ||||
|   | ||||
| @@ -14,10 +14,16 @@ services: | ||||
|     networks: | ||||
|       - nginx_proxy_manager | ||||
|     environment: | ||||
|       - NODE_ENV=development | ||||
|       - FORCE_COLOR=1 | ||||
|       - DEVELOPMENT=true | ||||
|       #- DISABLE_IPV6=true | ||||
|       NODE_ENV: "development" | ||||
|       FORCE_COLOR: 1 | ||||
|       DEVELOPMENT: "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: | ||||
|       - npm_data:/data | ||||
|       - 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-Compose Install documentation](https://docs.docker.com/compose/install/) | ||||
|  | ||||
| 2. Create a config file for example | ||||
| ```json | ||||
| { | ||||
|   "database": { | ||||
|     "engine": "mysql", | ||||
|     "host": "db", | ||||
|     "name": "npm", | ||||
|     "user": "npm", | ||||
|     "password": "npm", | ||||
|     "port": 3306 | ||||
|   } | ||||
| } | ||||
| ``` | ||||
|  | ||||
| 3. Create a docker-compose.yml file similar to this: | ||||
| 2. Create a docker-compose.yml file similar to this: | ||||
|  | ||||
| ```yml | ||||
| version: '3' | ||||
| @@ -70,8 +56,13 @@ services: | ||||
|       - '80:80' | ||||
|       - '81:81' | ||||
|       - '443:443' | ||||
|     environment: | ||||
|       DB_MYSQL_HOST: "db" | ||||
|       DB_MYSQL_PORT: 3306 | ||||
|       DB_MYSQL_USER: "npm" | ||||
|       DB_MYSQL_PASSWORD: "npm" | ||||
|       DB_MYSQL_NAME: "npm" | ||||
|     volumes: | ||||
|       - ./config.json:/app/config/production.json | ||||
|       - ./data:/data | ||||
|       - ./letsencrypt:/etc/letsencrypt | ||||
|   db: | ||||
| @@ -85,13 +76,13 @@ services: | ||||
|       - ./data/mysql:/var/lib/mysql | ||||
| ``` | ||||
|  | ||||
| 4. Bring up your stack | ||||
| 3. Bring up your stack | ||||
|  | ||||
| ```bash | ||||
| 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. | ||||
| Sometimes this can take a little bit because of the entropy of keys. | ||||
|   | ||||
| @@ -1,50 +1,5 @@ | ||||
| # 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 | ||||
|  | ||||
| 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 | ||||
|  | ||||
| Via `docker-compose`: | ||||
| @@ -80,11 +34,18 @@ services: | ||||
|       # Admin Web Port: | ||||
|       - '81:81' | ||||
|     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 | ||||
|       # DISABLE_IPV6: 'true' | ||||
|     volumes: | ||||
|       # Make sure this config.json file exists as per instructions above: | ||||
|       - ./config.json:/app/config/production.json | ||||
|       - ./data:/data | ||||
|       - ./letsencrypt:/etc/letsencrypt | ||||
|     depends_on: | ||||
| @@ -101,14 +62,14 @@ services: | ||||
|       - ./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: | ||||
|  | ||||
| ```bash | ||||
| docker-compose up -d | ||||
| ``` | ||||
|  | ||||
| The config file (config.json) must be present in this directory. | ||||
|  | ||||
| ### Running on Raspberry PI / ARM devices | ||||
|  | ||||
| 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. | ||||
|  | ||||
| ### 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