diff --git a/Dockerfile b/Dockerfile index 6da6bbbc..4a5b2e80 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,11 +19,11 @@ RUN curl -L -o /tmp/s6-overlay-amd64.tar.gz "https://github.com/just-containers/ # App ENV NODE_ENV=production -ADD dist /srv/app/dist -ADD node_modules /srv/app/node_modules -ADD src/backend /srv/app/src/backend -ADD package.json /srv/app/package.json -ADD knexfile.js /srv/app/knexfile.js +ADD dist /app/dist +ADD node_modules /app/node_modules +ADD src/backend /app/src/backend +ADD package.json /app/package.json +ADD knexfile.js /app/knexfile.js # Volumes VOLUME [ "/data", "/etc/letsencrypt" ] diff --git a/Dockerfile.armhf b/Dockerfile.armhf index 65cd528b..537b6d40 100644 --- a/Dockerfile.armhf +++ b/Dockerfile.armhf @@ -19,11 +19,11 @@ RUN curl -L -o /tmp/s6-overlay-armhf.tar.gz "https://github.com/just-containers/ # App ENV NODE_ENV=production -ADD dist /srv/app/dist -ADD node_modules /srv/app/node_modules -ADD src/backend /srv/app/src/backend -ADD package.json /srv/app/package.json -ADD knexfile.js /srv/app/knexfile.js +ADD dist /app/dist +ADD node_modules /app/node_modules +ADD src/backend /app/src/backend +ADD package.json /app/package.json +ADD knexfile.js /app/knexfile.js # Volumes VOLUME [ "/data", "/etc/letsencrypt" ] diff --git a/README.md b/README.md index 657905eb..cba99e78 100644 --- a/README.md +++ b/README.md @@ -19,52 +19,17 @@ running at home or otherwise, including free SSL, without having to know too muc ## Getting started -### Method 1: Using docker-compose +Please consult the [installation instructions](doc/INSTALL.md) for a complete guide or +if you just want to get up and running in the quickest time possible, grab all the files in the `doc/example/` folder and run `docker-compose up -d` -By far the easiest way to get up and running. Create this `docker-compose.yml` - -```yml -version: "2" -services: - app: - image: jc21/nginx-proxy-manager:preview - ports: - - 80:80 - - 81:81 - - 443:443 - volumes: - - ./data:/data - - ./letsencrypt:/etc/letsencrypt -``` - -Then: - -```bash -docker-compose up -d -``` - - -### Method 2: Using vanilla docker - -```bash -docker run -d \ - -p 80:80 \ - -p 81:81 \ - -p 443:443 \ - -v /path/to/data:/data \ - -v /path/to/letsencrypt:/etc/letsencrypt \ - jc21/nginx-proxy-manager -``` ## Administration -Now that 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. [http://localhost:81](http://localhost:81) -From here, the rest should be self explanatory. - Note: Requesting SSL Certificates won't work until this project is accessible from the outside world, as explained below. @@ -75,6 +40,8 @@ Email: admin@example.com Password: changeme ``` +Immediately after logging in with this default user you will be asked to modify your details and change your password. + ## Hosting your home network diff --git a/config/default.json b/config/default.json index 1cfccb1e..64ab577c 100644 --- a/config/default.json +++ b/config/default.json @@ -1,10 +1,10 @@ { - "database": { - "engine": "mysql", - "host": "db", - "name": "npm", - "user": "npm", - "password": "npm", - "port": 3306 - } + "database": { + "engine": "mysql", + "host": "db", + "name": "npm", + "user": "npm", + "password": "npm", + "port": 3306 + } } diff --git a/doc/INSTALL.md b/doc/INSTALL.md new file mode 100644 index 00000000..bed26b3e --- /dev/null +++ b/doc/INSTALL.md @@ -0,0 +1,140 @@ +## Installation and Configuration + +There's a few ways to configure this app depending on: + +- Whether you use `docker-compose` or vanilla docker +- Which Database you want to use (mysql or postgres) +- Which architecture you're running it on (raspberry pi also supported) + +### 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 and where it is. + +Here's an example configuration for `mysql`: + +```json +{ + "database": { + "engine": "mysql", + "host": "127.0.0.1", + "name": "nginxproxymanager", + "user": "nginxproxymanager", + "password": "password123", + "port": 3306 + } +} +``` + +and here's one for `postgres`: + +```json +{ + "database": { + "engine": "pg", + "version": "7.2", + "host": "127.0.0.1", + "name": "nginxproxymanager", + "user": "nginxproxymanager", + "password": "password123", + "port": 5432 + } +} +``` + +Once you've created your configuration file it's easy to mount it in the docker container, examples below. + +**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. + + +### Database + +This app doesn't come with a database, you have to provide one yourself. Currently `mysql` and `postgres` databases are supported. + +It's easy to use another docker container for your database also and link it as part of the docker stack. Here's an example: + +```yml +version: "3" +services: + app: + image: jc21/nginx-proxy-manager:2 + restart: always + network_mode: host + volumes: + - ./config.json:/app/config/production.json + - ./data:/data + - ./letsencrypt:/etc/letsencrypt + depends_on: + - db + db: + image: mariadb + restart: always + environment: + MYSQL_ROOT_PASSWORD: "password123" + MYSQL_DATABASE: "nginxproxymanager" + MYSQL_USER: "nginxproxymanager" + MYSQL_PASSWORD: "password123" + volumes: + - ./data/mysql:/var/lib/mysql +``` + + +### Running the App + +Via `docker-compose`: + +```yml +version: "3" +services: + app: + image: jc21/nginx-proxy-manager:2 + restart: always + network_mode: host + volumes: + - ./config.json:/app/config/production.json + - ./data:/data + - ./letsencrypt:/etc/letsencrypt +``` + +Vanilla Docker: + +```bash +docker run -d \ + --name nginx-proxy-manager \ + --network host \ + -v /path/to/config.json:/app/config/production.json \ + -v /path/to/data:/data \ + -v /path/to/letsencrypt:/etc/letsencrypt \ + jc21/nginx-proxy-manager:2 +``` + + +### Running on Raspberry PI / `armhf` + +I have created a `armhf` docker container just for you. There may be issues with it, +if you have issues please report them here. + +```bash +# Postgres: +docker run -d \ + --name nginx-proxy-manager-db \ + --network host \ + -e POSTGRES_DB=nginxproxymanager \ + -e POSTGRES_USER=nginxproxymanager \ + -e POSTGRES_PASSWORD=password123 \ + -v /path/to/postgresql:/var/lib/postgresql/data \ + zsoltm/postgresql-armhf + +# NPM: +docker run -d \ + --name nginx-proxy-manager-app \ + --network host \ + -v /path/to/config.json:/app/config/production.json \ + -v /path/to/data:/data \ + -v /path/to/letsencrypt:/etc/letsencrypt \ + jc21/nginx-proxy-manager:2-armhf +``` diff --git a/doc/example/config.json b/doc/example/config.json new file mode 100644 index 00000000..dfc9f049 --- /dev/null +++ b/doc/example/config.json @@ -0,0 +1,10 @@ +{ + "database": { + "engine": "mysql", + "host": "db", + "name": "nginxproxymanager", + "user": "nginxproxymanager", + "password": "password123", + "port": 3306 + } +} diff --git a/doc/example/docker-compose.yml b/doc/example/docker-compose.yml new file mode 100644 index 00000000..853f3e58 --- /dev/null +++ b/doc/example/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3" +services: + app: + image: jc21/nginx-proxy-manager:2 + restart: always + network_mode: host + volumes: + - ./config.json:/app/config/production.json + - ./data:/data + - ./letsencrypt:/etc/letsencrypt + depends_on: + - db + db: + image: mariadb + restart: always + environment: + MYSQL_ROOT_PASSWORD: "password123" + MYSQL_DATABASE: "nginxproxymanager" + MYSQL_USER: "nginxproxymanager" + MYSQL_PASSWORD: "password123" + volumes: + - ./data/mysql:/var/lib/mysql diff --git a/rootfs/etc/services.d/manager/run b/rootfs/etc/services.d/manager/run index 64beac83..598f86af 100755 --- a/rootfs/etc/services.d/manager/run +++ b/rootfs/etc/services.d/manager/run @@ -3,4 +3,4 @@ mkdir -p /data/letsencrypt-acme-challenge cd /srv/app -node --abort_on_uncaught_exception --max_old_space_size=250 /srv/app/src/backend/index.js +node --abort_on_uncaught_exception --max_old_space_size=250 /app/src/backend/index.js diff --git a/src/backend/db.js b/src/backend/db.js index 124c64bb..6fcf831e 100644 --- a/src/backend/db.js +++ b/src/backend/db.js @@ -1,12 +1,12 @@ 'use strict'; -let config = require('config'); +const config = require('config'); if (!config.has('database')) { - throw new Error('Database config does not exist! Read the README for instructions.'); + throw new Error('Database config does not exist! Please read the instructions: https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md'); } -let knex = require('knex')({ +let data = { client: config.database.engine, connection: { host: config.database.host, @@ -18,6 +18,10 @@ let knex = require('knex')({ migrations: { tableName: 'migrations' } -}); +}; -module.exports = knex; +if (typeof config.database.version !== 'undefined') { + data.version = config.database.version; +} + +module.exports = require('knex')(data); diff --git a/src/backend/index.js b/src/backend/index.js index 5ced24c0..0aae9bfe 100644 --- a/src/backend/index.js +++ b/src/backend/index.js @@ -2,20 +2,14 @@ 'use strict'; -const config = require('config'); -const app = require('./app'); -const logger = require('./logger').global; -const migrate = require('./migrate'); -const setup = require('./setup'); -const apiValidator = require('./lib/validator/api'); - -let port = process.env.PORT || 81; - -if (config.has('port')) { - port = config.get('port'); -} +const logger = require('./logger').global; function appStart () { + const migrate = require('./migrate'); + const setup = require('./setup'); + const app = require('./app'); + const apiValidator = require('./lib/validator/api'); + return migrate.latest() .then(() => { return setup(); @@ -24,8 +18,8 @@ function appStart () { return apiValidator.loadSchemas; }) .then(() => { - const server = app.listen(port, () => { - logger.info('PID ' + process.pid + ' listening on port ' + port + ' ...'); + const server = app.listen(81, () => { + logger.info('PID ' + process.pid + ' listening on port 81 ...'); process.on('SIGTERM', () => { logger.info('PID ' + process.pid + ' received SIGTERM'); @@ -42,4 +36,9 @@ function appStart () { }); } -appStart(); +try { + appStart(); +} catch (err) { + logger.error(err.message); + process.exit(1); +}