diff --git a/core/server/ghost-server.js b/core/server/ghost-server.js index e207099c58..c117dfc7b4 100644 --- a/core/server/ghost-server.js +++ b/core/server/ghost-server.js @@ -196,6 +196,15 @@ class GhostServer { } } + /** + * @param {Object} externalApp - express app instance + * @return {Promise} Resolves once Ghost has switched HTTP Servers + */ + async swapHttpApp(externalApp) { + await this._stopServer(); + await this.start(externalApp); + } + /** * ### Hammertime * To be called after `stop` diff --git a/core/server/index.js b/core/server/index.js index bd4b0ba2c6..2a69273213 100644 --- a/core/server/index.js +++ b/core/server/index.js @@ -93,6 +93,10 @@ const initExpressApps = async () => { return parentApp; }; +const initMaintenanceApp = () => { + return require('./web/maintenance')(); +}; + /** * - initialise models * - initialise i18n @@ -138,25 +142,26 @@ const minimalRequiredSetupToStartGhost = async (dbState) => { config.set('maintenance:enabled', true); logging.info('Blog is in maintenance mode.'); + ghostServer.rootApp = initMaintenanceApp(); + try { - // const delay= ms => new Promise(resolve => setTimeout(resolve ,ms)); - await migrator.migrate(); + migrator.migrate() + .then(async () => { + await settings.init(); + debug('Settings done'); - // await delay(10000); - await settings.init(); - debug('Settings done'); + const parentApp = await initExpressApps(); + ghostServer.swapHttpApp(parentApp); - const parentApp = await initExpressApps(); - ghostServer.rootApp = parentApp; + events.emit('db.ready'); - events.emit('db.ready'); + await initialiseServices(); - await initialiseServices(); + config.set('maintenance:enabled', false); + logging.info('Blog is out of maintenance mode.'); - config.set('maintenance:enabled', false); - logging.info('Blog is out of maintenance mode.'); - - await GhostServer.announceServerReadiness(); + await GhostServer.announceServerReadiness(); + }); } catch (err) { try { await GhostServer.announceServerReadiness(err); diff --git a/core/server/web/maintenance/index.js b/core/server/web/maintenance/index.js new file mode 100644 index 0000000000..55f2a0461b --- /dev/null +++ b/core/server/web/maintenance/index.js @@ -0,0 +1,51 @@ +const hbs = require('express-hbs'); +const compress = require('compression'); +const debug = require('ghost-ignition').debug('web:maintenance'); +const constants = require('@tryghost/constants'); +const express = require('../../../shared/express'); +const config = require('../../../shared/config'); +const {servePublicFile} = require('../site/middleware'); + +const createHbsEngine = () => { + const engine = hbs.create(); + engine.registerHelper('asset', require('../../../frontend/helpers/asset')); + + return engine.express4(); +}; + +module.exports = function setupMaintenanceApp() { + debug('MaintenanceApp setup start'); + const app = express('maintenance'); + + // enabled gzip compression by defaulti + if (config.get('compress') !== false) { + app.use(compress()); + } + + app.engine('hbs', createHbsEngine()); + app.set('view engine', 'hbs'); + app.set('views', config.get('paths').defaultViews); + + // Serve stylesheets for default templates + app.use(servePublicFile('public/ghost.css', 'text/css', constants.ONE_HOUR_S)); + app.use(servePublicFile('public/ghost.min.css', 'text/css', constants.ONE_YEAR_S)); + + // Serve images for default templates + app.use(servePublicFile('public/404-ghost@2x.png', 'image/png', constants.ONE_HOUR_S)); + app.use(servePublicFile('public/404-ghost.png', 'image/png', constants.ONE_HOUR_S)); + + app.use('/', (req, res) => { + const data = { + message: 'Maintenance', + statusCode: 503 + }; + + res.render('error', data, (err, html) => { + return res.send(html); + }); + }); + + debug('MaintenanceApp setup end'); + + return app; +};