Added support for Heroku + config wizard fixes

This commit is contained in:
NGPixel 2017-04-18 20:23:42 -04:00
parent 1d8285fb6a
commit 32ac3a9fac
7 changed files with 155 additions and 80 deletions

View File

@ -125,7 +125,8 @@ module.exports = (port, spinner) => {
*/ */
app.post('/dbcheck', (req, res) => { app.post('/dbcheck', (req, res) => {
let mongo = require('mongodb').MongoClient let mongo = require('mongodb').MongoClient
mongo.connect(req.body.db, { let mongoURI = (_.startsWith(req.body.db, '$')) ? process.env[req.body.db.slice(1)] : req.body.db
mongo.connect(mongoURI, {
autoReconnect: false, autoReconnect: false,
reconnectTries: 2, reconnectTries: 2,
reconnectInterval: 1000, reconnectInterval: 1000,

View File

@ -82,7 +82,6 @@ const SHIMS = {
console.info(colors.white('└── ') + colors.green('Running global tasks...')) console.info(colors.white('└── ') + colors.green('Running global tasks...'))
let preInitContent = ''
let globalTasks = Promise.mapSeries([ let globalTasks = Promise.mapSeries([
/** /**
* ACE Modes * ACE Modes
@ -161,6 +160,7 @@ let globalTasks = Promise.mapSeries([
*/ */
() => { () => {
console.info(colors.white(' └── ') + colors.green('Bundling pre-init scripts...')) console.info(colors.white(' └── ') + colors.green('Bundling pre-init scripts...'))
let preInitContent = ''
return fs.readdirAsync('./client/js/pre-init').map(f => { return fs.readdirAsync('./client/js/pre-init').map(f => {
let fPath = path.join('./client/js/pre-init/', f) let fPath = path.join('./client/js/pre-init/', f)
return fs.readFileAsync(fPath, 'utf8').then(fContent => { return fs.readFileAsync(fPath, 'utf8').then(fContent => {
@ -275,7 +275,6 @@ globalTasks.then(() => {
shim: SHIMS, shim: SHIMS,
plugins: [ plugins: [
fsbx.EnvPlugin({ NODE_ENV: 'production' }), fsbx.EnvPlugin({ NODE_ENV: 'production' }),
fsbx.BannerPlugin(preInitContent),
[ fsbx.SassPlugin({ outputStyle: 'compressed', includePaths: ['./node_modules/requarks-core'] }), fsbx.CSSPlugin() ], [ fsbx.SassPlugin({ outputStyle: 'compressed', includePaths: ['./node_modules/requarks-core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({ fsbx.BabelPlugin({
config: { config: {

101
init.js Normal file
View File

@ -0,0 +1,101 @@
'use strict'
const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs-extra'))
const pm2 = Promise.promisifyAll(require('pm2'))
const ora = require('ora')
const path = require('path')
module.exports = {
/**
* Detect the most appropriate start mode
*/
startDetect: function () {
if (!process.env.IS_HEROKU) {
return this.startInHerokuMode()
} else {
return this.startInBackgroundMode()
}
},
/**
* Start in background mode
*/
startInBackgroundMode: function () {
let spinner = ora('Initializing...').start()
return fs.emptyDirAsync(path.join(__dirname, './logs')).then(() => {
return pm2.connectAsync().then(() => {
return pm2.startAsync({
name: 'wiki',
script: 'server.js',
cwd: __dirname,
output: path.join(__dirname, './logs/wiki-output.log'),
error: path.join(__dirname, './logs/wiki-error.log'),
minUptime: 5000,
maxRestarts: 5
}).then(() => {
spinner.succeed('Wiki.js has started successfully.')
}).finally(() => {
pm2.disconnect()
})
})
}).catch(err => {
spinner.fail(err)
process.exit(1)
})
},
/**
* Start in Heroku mode
*/
startInHerokuMode: function () {
let self = this
console.info('Initializing Wiki.js for Heroku...')
let herokuStatePath = path.join(__dirname, './app/heroku.json')
return fs.accessAsync(herokuStatePath).then(() => {
require('./server.js')
}).catch(err => {
if (err.code === 'ENOENT') {
console.info('Wiki.js is not configured yet. Launching configuration wizard...')
self.configure(process.env.PORT)
} else {
console.error(err)
process.exit(1)
}
})
},
/**
* Stop Wiki.js process(es)
*/
stop () {
let spinner = ora('Shutting down Wiki.js...').start()
return pm2.connectAsync().then(() => {
return pm2.stopAsync('wiki').then(() => {
spinner.succeed('Wiki.js has stopped successfully.')
}).finally(() => {
pm2.disconnect()
})
}).catch(err => {
spinner.fail(err)
process.exit(1)
})
},
/**
* Restart Wiki.js process(es)
*/
restart: function () {
let self = this
return self.stop().delay(1000).then(() => {
self.startDetect()
})
},
/**
* Start the web-based configuration wizard
*
* @param {Number} port Port to bind the HTTP server on
*/
configure (port) {
port = port || 3000
let spinner = ora('Initializing interactive setup...').start()
require('./configure')(port, spinner)
}
}

View File

@ -205,13 +205,15 @@ const tasks = {
// INSTALL SEQUENCE // INSTALL SEQUENCE
// ===================================================== // =====================================================
console.info(colors.yellow( if (!process.env.IS_HEROKU) {
' __ __ _ _ _ _ \n' + console.info(colors.yellow(
'/ / /\\ \\ (_) | _(_) (_)___ \n' + ' __ __ _ _ _ _ \n' +
'\\ \\/ \\/ / | |/ / | | / __| \n' + '/ / /\\ \\ (_) | _(_) (_)___ \n' +
' \\ /\\ /| | <| |_ | \\__ \\ \n' + '\\ \\/ \\/ / | |/ / | | / __| \n' +
' \\/ \\/ |_|_|\\_\\_(_)/ |___/ \n' + ' \\ /\\ /| | <| |_ | \\__ \\ \n' +
' |__/\n')) ' \\/ \\/ |_|_|\\_\\_(_)/ |___/ \n' +
' |__/\n'))
}
let ora = require('ora')({ text: 'Initializing...', spinner: 'dots12' }).start() let ora = require('ora')({ text: 'Initializing...', spinner: 'dots12' }).start()

View File

@ -47,7 +47,6 @@
"cheerio": "^0.22.0", "cheerio": "^0.22.0",
"child-process-promise": "^2.2.1", "child-process-promise": "^2.2.1",
"chokidar": "^1.6.1", "chokidar": "^1.6.1",
"commander": "^2.9.0",
"compression": "^1.6.2", "compression": "^1.6.2",
"connect-flash": "^0.1.1", "connect-flash": "^0.1.1",
"connect-mongo": "^1.3.2", "connect-mongo": "^1.3.2",
@ -120,7 +119,8 @@
"through2": "^2.0.3", "through2": "^2.0.3",
"validator": "^7.0.0", "validator": "^7.0.0",
"validator-as-promised": "^1.0.2", "validator-as-promised": "^1.0.2",
"winston": "^2.3.1" "winston": "^2.3.1",
"yargs": "^7.1.0"
}, },
"devDependencies": { "devDependencies": {
"babel-cli": "^6.24.1", "babel-cli": "^6.24.1",

View File

@ -160,8 +160,8 @@ html(data-logic='configure')
section section
p.control.is-fullwidth p.control.is-fullwidth
label.label MongoDB Connection String 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: 14 }') 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. 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 .panel-footer
.progress-bar: div(v-bind:style='{width: currentProgress}') .progress-bar: div(v-bind:style='{width: currentProgress}')
button.button.is-indigo.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back button.button.is-indigo.is-outlined(v-on:click='proceedToConsiderations', v-bind:disabled='loading') Back

104
wiki.js
View File

@ -7,74 +7,46 @@
// Licensed under AGPLv3 // Licensed under AGPLv3
// =========================================== // ===========================================
const Promise = require('bluebird') const init = require('./init')
const fs = Promise.promisifyAll(require('fs-extra'))
const ora = require('ora')
const pm2 = Promise.promisifyAll(require('pm2'))
const cmdr = require('commander')
const path = require('path')
const packageObj = fs.readJsonSync('package.json') require('yargs') // eslint-disable-line no-unused-expressions
.usage('Usage: node $0 <cmd> [args]')
cmdr.version(packageObj.version) .command({
command: 'start',
cmdr.command('start') alias: ['boot', 'init'],
.description('Start Wiki.js process') desc: 'Start Wiki.js process',
.action(() => { handler: argv => {
if (process.env.HEROKU) { init.startDetect()
console.info('Initializing Wiki.js for Heroku...')
// todo
} else {
let spinner = ora('Initializing...').start()
fs.emptyDirAsync(path.join(__dirname, './logs')).then(() => {
return pm2.connectAsync().then(() => {
return pm2.startAsync({
name: 'wiki',
script: 'server.js',
cwd: __dirname,
output: path.join(__dirname, './logs/wiki-output.log'),
error: path.join(__dirname, './logs/wiki-error.log'),
minUptime: 5000,
maxRestarts: 5
}).then(() => {
spinner.succeed('Wiki.js has started successfully.')
}).finally(() => {
pm2.disconnect()
})
})
}).catch(err => {
spinner.fail(err)
process.exit(1)
})
} }
}) })
.command({
cmdr.command('stop') command: 'stop',
.description('Stop Wiki.js process') alias: ['quit', 'exit'],
.action(() => { desc: 'Stop Wiki.js process',
let spinner = ora('Shutting down Wiki.js...').start() handler: argv => {
pm2.connectAsync().then(() => { init.stop()
return pm2.stopAsync('wiki').then(() => { }
spinner.succeed('Wiki.js has stopped successfully.')
}).finally(() => {
pm2.disconnect()
})
}).catch(err => {
spinner.fail(err)
process.exit(1)
})
}) })
.command({
cmdr.command('configure [port]') command: 'restart',
.description('Configure Wiki.js') alias: ['reload'],
.action((port) => { desc: 'Restart Wiki.js process',
port = port || 3000 handler: argv => {
let spinner = ora('Initializing interactive setup...').start() init.restart()
require('./configure')(port, spinner) }
}) })
.command({
cmdr.parse(process.argv) command: 'configure [port]',
alias: ['config', 'conf', 'cfg', 'setup'],
if (!process.argv.slice(2).length) { desc: 'Configure Wiki.js using the web-based setup wizard',
cmdr.help() builder: (yargs) => yargs.default('port', 3000),
} handler: argv => {
init.configure(argv.port)
}
})
.recommendCommands()
.demandCommand(1, 'You must provide one of the accepted commands above.')
.help()
.version()
.epilogue('Read the docs at https://wiki.requarks.io')
.argv