feat: Heroku support - setup
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| 'use strict' | ||||
|  | ||||
| /* global appconfig */ | ||||
| /* global appconfig, runmode */ | ||||
|  | ||||
| import jQuery from 'jquery' | ||||
| import _ from 'lodash' | ||||
| @@ -180,6 +180,9 @@ jQuery(document).ready(function ($) { | ||||
|       }, | ||||
|       proceedToDb: function (ev) { | ||||
|         let self = this | ||||
|         if (runmode.staticMongo) { | ||||
|           return self.proceedToDbcheck() | ||||
|         } | ||||
|         self.state = 'db' | ||||
|         self.loading = false | ||||
|         self.$nextTick(() => { | ||||
|   | ||||
							
								
								
									
										153
									
								
								npm/configs/config.heroku.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								npm/configs/config.heroku.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| ####################################################################### | ||||
| # Wiki.js - CONFIGURATION                                             # | ||||
| ####################################################################### | ||||
| # Full explanation + examples in the documentation: | ||||
| # https://docs.requarks.io/wiki/install | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Title of this site | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| title: Wiki | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Full public path to the site, without the trailing slash | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| host: https://YOURAPP.herokuapp.com/ | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Port the main server should listen to (80 by default) | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| port: $(PORT) | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Data Directories | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| paths: | ||||
|   repo: ./repo | ||||
|   data: ./data | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Upload Limits | ||||
| # --------------------------------------------------------------------- | ||||
| # In megabytes (MB) | ||||
|  | ||||
| uploads: | ||||
|   maxImageFileSize: 3 | ||||
|   maxOtherFileSize: 100 | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Site Language | ||||
| # --------------------------------------------------------------------- | ||||
| # Possible values: en, de, es, fr, ko, pt or ru | ||||
|  | ||||
| lang: en | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Site Authentication | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| public: false | ||||
|  | ||||
| auth: | ||||
|   defaultReadAccess: false | ||||
|   local: | ||||
|     enabled: true | ||||
|   google: | ||||
|     enabled: true | ||||
|     clientId: GOOGLE_CLIENT_ID | ||||
|     clientSecret: GOOGLE_CLIENT_SECRET | ||||
|   microsoft: | ||||
|     enabled: true | ||||
|     clientId: MS_APP_ID | ||||
|     clientSecret: MS_APP_SECRET | ||||
|   facebook: | ||||
|     enabled: false | ||||
|     clientId: FACEBOOK_APP_ID | ||||
|     clientSecret: FACEBOOK_APP_SECRET | ||||
|   github: | ||||
|     enabled: false | ||||
|     clientId: GITHUB_CLIENT_ID | ||||
|     clientSecret: GITHUB_CLIENT_SECRET | ||||
|   slack: | ||||
|     enabled: false | ||||
|     clientId: SLACK_CLIENT_ID | ||||
|     clientSecret: SLACK_CLIENT_SECRET | ||||
|   ldap: | ||||
|     enabled: false | ||||
|     url: ldap://serverhost:389 | ||||
|     bindDn: cn='root' | ||||
|     bindCredentials: BIND_PASSWORD | ||||
|     searchBase: o=users,o=example.com | ||||
|     searchFilter: (uid={{username}}) | ||||
|     tlsEnabled: false | ||||
|     tlsCertPath: C:\example\root_ca_cert.crt | ||||
|   azure: | ||||
|     enabled: false | ||||
|     clientID: APP_ID | ||||
|     clientSecret: APP_SECRET_KEY | ||||
|     resource: '00000002-0000-0000-c000-000000000000' | ||||
|     tenant: 'YOUR_TENANT.onmicrosoft.com' | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Secret key to use when encrypting sessions | ||||
| # --------------------------------------------------------------------- | ||||
| # Use a long and unique random string (256-bit keys are perfect!) | ||||
|  | ||||
| sessionSecret: 1234567890abcdefghijklmnopqrstuvxyz | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Database Connection String | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| db: $(MONGO_URI) | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Git Connection Info | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| git: | ||||
|   url: https://github.com/Organization/Repo | ||||
|   branch: master | ||||
|   auth: | ||||
|  | ||||
|     # Type: basic or ssh | ||||
|     type: ssh | ||||
|  | ||||
|     # Only for Basic authentication: | ||||
|     username: marty | ||||
|     password: MartyMcFly88 | ||||
|  | ||||
|     # Only for SSH authentication: | ||||
|     privateKey: /etc/wiki/keys/git.pem | ||||
|  | ||||
|     sslVerify: true | ||||
|  | ||||
|   # Default email to use as commit author | ||||
|   serverEmail: marty@example.com | ||||
|  | ||||
|   # Whether to use user email as author in commits | ||||
|   showUserEmail: true | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # Features | ||||
| # --------------------------------------------------------------------- | ||||
| # You can enable / disable specific features below | ||||
|  | ||||
| features: | ||||
|   mathjax: true | ||||
|  | ||||
| # --------------------------------------------------------------------- | ||||
| # External Logging | ||||
| # --------------------------------------------------------------------- | ||||
|  | ||||
| externalLogging: | ||||
|   bugsnag: false | ||||
|   loggly: false | ||||
|   papertrail: false | ||||
|   rollbar: false | ||||
|   sentry: false | ||||
|  | ||||
| @@ -136,11 +136,13 @@ const tasks = { | ||||
|       // Is New Install | ||||
|       if (err.code === 'ENOENT') { | ||||
|         ora.text = 'First-time install, creating a new config.yml...' | ||||
|         let sourceConfigFile = 'config.sample.yml' | ||||
|         if (process.env.WIKI_JS_DOCKER) { | ||||
|           sourceConfigFile = 'config.docker.yml' | ||||
|         let sourceConfigFile = path.join(installDir, 'config.sample.yml') | ||||
|         if (process.env.IS_HEROKU) { | ||||
|           sourceConfigFile = path.join(__dirname, 'configs/config.heroku.yml') | ||||
|         } else if (process.env.WIKI_JS_DOCKER) { | ||||
|           sourceConfigFile = path.join(__dirname, 'configs/config.docker.yml') | ||||
|         } | ||||
|         return fs.copyAsync(path.join(installDir, sourceConfigFile), path.join(installDir, 'config.yml')).then(() => { | ||||
|         return fs.copyAsync(sourceConfigFile, path.join(installDir, 'config.yml')).then(() => { | ||||
|           ora.succeed('Installation succeeded.') | ||||
|           return true | ||||
|         }) | ||||
| @@ -200,7 +202,11 @@ const tasks = { | ||||
|         }) | ||||
|       }) | ||||
|     } else { | ||||
|       if (!process.env.IS_HEROKU && !process.env.WIKI_JS_DOCKER) { | ||||
|         console.info(colors.cyan('[WARNING] Non-interactive terminal detected. You must manually start the configuration wizard using the command: node wiki configure')) | ||||
|       } else { | ||||
|         console.info('Container environment detected. Skipping setup wizard auto-start. OK.') | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -217,6 +223,8 @@ if (!process.env.IS_HEROKU && !process.env.WIKI_JS_DOCKER) { | ||||
|     ' \\  /\\  /| |   <| |_ | \\__ \\ \n' + | ||||
|     '  \\/  \\/ |_|_|\\_\\_(_)/ |___/ \n' + | ||||
|     '                   |__/\n')) | ||||
| } else { | ||||
|   console.info('=-=-= WIKI.JS =-=-=') | ||||
| } | ||||
|  | ||||
| let ora = require('ora')({ text: 'Initializing...', spinner: 'dots12' }).start() | ||||
|   | ||||
| @@ -20,6 +20,7 @@ module.exports = (port, spinner) => { | ||||
|   const fs = Promise.promisifyAll(require('fs-extra')) | ||||
|   const yaml = require('js-yaml') | ||||
|   const _ = require('lodash') | ||||
|   const cfgHelper = require('./helpers/config') | ||||
|  | ||||
|   // ---------------------------------------- | ||||
|   // Define Express App | ||||
| @@ -62,7 +63,14 @@ module.exports = (port, spinner) => { | ||||
|     } catch (err) { | ||||
|       console.error(err) | ||||
|     } | ||||
|     res.render('configure/index', { langs, conf }) | ||||
|     res.render('configure/index', { | ||||
|       langs, | ||||
|       conf, | ||||
|       runmode: { | ||||
|         staticPort: (process.env.IS_HEROKU || process.env.WIKI_JS_DOCKER) || true, | ||||
|         staticMongo: (!_.isNil(process.env.IS_HEROKU)) || true | ||||
|       } | ||||
|     }) | ||||
|   }) | ||||
|  | ||||
|   /** | ||||
| @@ -127,7 +135,7 @@ module.exports = (port, spinner) => { | ||||
|    */ | ||||
|   app.post('/dbcheck', (req, res) => { | ||||
|     let mongo = require('mongodb').MongoClient | ||||
|     let mongoURI = (_.startsWith(req.body.db, '$')) ? process.env[req.body.db.slice(1)] : req.body.db | ||||
|     let mongoURI = cfgHelper.parseConfigValue(req.body.db) | ||||
|     mongo.connect(mongoURI, { | ||||
|       autoReconnect: false, | ||||
|       reconnectTries: 2, | ||||
| @@ -166,13 +174,13 @@ module.exports = (port, spinner) => { | ||||
|     const exec = require('execa') | ||||
|     const url = require('url') | ||||
|  | ||||
|     const dataDir = path.resolve(ROOTPATH, req.body.pathData) | ||||
|     const gitDir = path.resolve(ROOTPATH, req.body.pathRepo) | ||||
|     const dataDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathData)) | ||||
|     const gitDir = path.resolve(ROOTPATH, cfgHelper.parseConfigValue(req.body.pathRepo)) | ||||
|  | ||||
|     let gitRemoteUrl = '' | ||||
|  | ||||
|     if (req.body.gitUseRemote === true) { | ||||
|       let urlObj = url.parse(req.body.gitUrl) | ||||
|       let urlObj = url.parse(cfgHelper.parseConfigValue(req.body.gitUrl)) | ||||
|       if (req.body.gitAuthType === 'basic') { | ||||
|         urlObj.auth = req.body.gitAuthUser + ':' + req.body.gitAuthPass | ||||
|       } | ||||
| @@ -254,10 +262,11 @@ module.exports = (port, spinner) => { | ||||
|     const bcrypt = require('bcryptjs-then') | ||||
|     const crypto = Promise.promisifyAll(require('crypto')) | ||||
|     let mongo = require('mongodb').MongoClient | ||||
|     let parsedMongoConStr = cfgHelper.parseConfigValue(req.body.db) | ||||
|  | ||||
|     Promise.join( | ||||
|       new Promise((resolve, reject) => { | ||||
|         mongo.connect(req.body.db, { | ||||
|         mongo.connect(parsedMongoConStr, { | ||||
|           autoReconnect: false, | ||||
|           reconnectTries: 2, | ||||
|           reconnectInterval: 1000, | ||||
|   | ||||
							
								
								
									
										20
									
								
								server/helpers/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								server/helpers/config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| 'use strict' | ||||
|  | ||||
| const _ = require('lodash') | ||||
|  | ||||
| module.exports = { | ||||
|   /** | ||||
|    * Parse configuration value for environment vars | ||||
|    * | ||||
|    * @param {any} cfg Configuration value | ||||
|    * @returns Parse configuration value | ||||
|    */ | ||||
|   parseConfigValue (cfg) { | ||||
|     return _.replace( | ||||
|       cfg, | ||||
|       (/\$\([A-Z0-9_]+\)/g, | ||||
|       (m) => { return process.env[m] }) | ||||
|     ) | ||||
|   } | ||||
| } | ||||
|  | ||||
| @@ -12,6 +12,7 @@ html(data-logic='configure') | ||||
|     // JS / CSS | ||||
|     script(type='text/javascript'). | ||||
|       var appconfig = !{JSON.stringify(conf)}; | ||||
|       var runmode = !{JSON.stringify(runmode)}; | ||||
|     script(type='text/javascript', src='/js/configure.min.js') | ||||
|  | ||||
|   body | ||||
| @@ -89,13 +90,14 @@ html(data-logic='configure') | ||||
|                   section | ||||
|                     p.control.is-fullwidth | ||||
|                       label.label Host | ||||
|                       input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, url: true }') | ||||
|                       span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are not supported. | ||||
|                       input(type='text', placeholder='http://', v-model='conf.host', data-vv-scope='general', name='ipt-host', v-validate='{ required: true, min: 4 }') | ||||
|                       span.desc The full URL to your wiki, without the trailing slash. E.g.: http://wiki.domain.com. Note that sub-folders are #[u not supported]. | ||||
|                   if !runmode.staticPort | ||||
|                     section | ||||
|                       p.control | ||||
|                         label.label Port | ||||
|                       input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true, numeric: true, min_value: 0, max_value: 65535 }') | ||||
|                       span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>0</strong> to use $PORT system environment variable. | ||||
|                         input(type='text', placeholder='e.g. 80', v-model.number='conf.port', data-vv-scope='general', name='ipt-port', v-validate='{ required: true }') | ||||
|                         span.desc The port on which Wiki.js will listen to. Usually port 80 if connecting directly, or a random port (e.g. 3000) if using a web server in front of it.<br>Set <strong>$(PORT)</strong> to use PORT environment variable. | ||||
|                   section | ||||
|                     p.control | ||||
|                       label.label Site UI Language | ||||
| @@ -160,7 +162,7 @@ html(data-logic='configure') | ||||
|                     p.control.is-fullwidth | ||||
|                       label.label MongoDB Connection String | ||||
|                       input(type='text', placeholder='e.g. mongodb://localhost:27017/wiki', v-model='conf.db', data-vv-scope='db', name='ipt-db', v-validate='{ required: true, min: 3 }') | ||||
|                       span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string (e.g. $MONGO_URI). | ||||
|                       span.desc The connection string to your MongoDB server. Leave the default localhost value if MongoDB is installed on the same server.<br />You can also specify an environment variable as the connection string, e.g. $(MONGO_URI). | ||||
|                 .panel-footer | ||||
|                   .progress-bar: div(v-bind:style='{width: currentProgress}') | ||||
|                   button.button.is-light-blue.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back | ||||
|   | ||||
		Reference in New Issue
	
	Block a user