mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-25 11:55:03 +03:00
21bea79848
- Currently the new boot process breaks the loading of inactive themes because the theme loader event isn't wired until after the server.start event is fired - This is a WIP fix, there needs to be some bigger refactoring of the boot process once the old process is gone
190 lines
6.5 KiB
JavaScript
190 lines
6.5 KiB
JavaScript
// # The Ghost Boot Sequence
|
|
|
|
// IMPORTANT: The only global requires here should be debug + overrides
|
|
const debug = require('ghost-ignition').debug('boot');
|
|
require('./server/overrides');
|
|
// END OF GLOBAL REQUIRES
|
|
|
|
const initCore = async ({ghostServer}) => {
|
|
const settings = require('./server/services/settings');
|
|
const jobService = require('./server/services/jobs');
|
|
const models = require('./server/models');
|
|
const {events, i18n} = require('./server/lib/common');
|
|
|
|
ghostServer.registerCleanupTask(async () => {
|
|
await jobService.shutdown();
|
|
});
|
|
|
|
// Initialize Ghost core internationalization
|
|
i18n.init();
|
|
debug('Default i18n done for core');
|
|
|
|
models.init();
|
|
debug('Models done');
|
|
|
|
await settings.init();
|
|
|
|
// @TODO: fix this - has to happen before db.ready is emitted
|
|
debug('Begin: Url Service');
|
|
require('./frontend/services/url');
|
|
debug('End: Url Service');
|
|
|
|
// @TODO: fix this location
|
|
events.emit('db.ready');
|
|
};
|
|
|
|
const initExpressApps = async () => {
|
|
debug('Begin: initExpressApps');
|
|
const themeService = require('./frontend/services/themes');
|
|
const frontendSettings = require('./frontend/services/settings');
|
|
|
|
await frontendSettings.init();
|
|
debug('Frontend settings done');
|
|
|
|
await themeService.init();
|
|
debug('Themes done');
|
|
|
|
const parentApp = require('./server/web/parent/app')();
|
|
|
|
// @TODO: fix this
|
|
const {events} = require('./server/lib/common');
|
|
events.emit('themes.ready');
|
|
|
|
debug('End: initExpressApps');
|
|
return parentApp;
|
|
};
|
|
|
|
const initServices = async ({config}) => {
|
|
debug('Begin: initialiseServices');
|
|
const themeService = require('./frontend/services/themes');
|
|
const frontendSettings = require('./frontend/services/settings');
|
|
const appService = require('./frontend/services/apps');
|
|
const urlUtils = require('./shared/url-utils');
|
|
|
|
// CASE: When Ghost is ready with bootstrapping (db migrations etc.), we can trigger the router creation.
|
|
// Reason is that the routers access the routes.yaml, which shouldn't and doesn't have to be validated to
|
|
// start Ghost in maintenance mode.
|
|
// Routing is a bridge between the frontend and API
|
|
const routing = require('./frontend/services/routing');
|
|
// We pass the themeService API version here, so that the frontend services are less tightly-coupled
|
|
routing.bootstrap.start(themeService.getApiVersion());
|
|
|
|
const settings = require('./server/services/settings');
|
|
const permissions = require('./server/services/permissions');
|
|
const xmlrpc = require('./server/services/xmlrpc');
|
|
const slack = require('./server/services/slack');
|
|
const {mega} = require('./server/services/mega');
|
|
const webhooks = require('./server/services/webhooks');
|
|
const scheduling = require('./server/adapters/scheduling');
|
|
const getRoutesHash = () => frontendSettings.getCurrentHash('routes');
|
|
|
|
await Promise.all([
|
|
// Initialize the permissions actions and objects
|
|
permissions.init(),
|
|
xmlrpc.listen(),
|
|
slack.listen(),
|
|
mega.listen(),
|
|
webhooks.listen(),
|
|
settings.syncRoutesHash(getRoutesHash),
|
|
appService.init(),
|
|
scheduling.init({
|
|
// NOTE: When changing API version need to consider how to migrate custom scheduling adapters
|
|
// that rely on URL to lookup persisted scheduled records (jobs, etc.). Ref: https://github.com/TryGhost/Ghost/pull/10726#issuecomment-489557162
|
|
apiUrl: urlUtils.urlFor('api', {version: 'v3', versionType: 'admin'}, true)
|
|
})
|
|
]);
|
|
|
|
debug('XMLRPC, Slack, MEGA, Webhooks, Scheduling, Permissions done');
|
|
|
|
// Initialise analytics events
|
|
if (config.get('segment:key')) {
|
|
require('./server/analytics-events').init();
|
|
}
|
|
|
|
debug('End: initialiseServices');
|
|
};
|
|
|
|
const mountGhost = (rootApp, ghostApp) => {
|
|
const urlService = require('./frontend/services/url');
|
|
rootApp.disable('maintenance');
|
|
rootApp.use(urlService.utils.getSubdir(), ghostApp);
|
|
};
|
|
|
|
const bootGhost = async () => {
|
|
// Metrics & debugging
|
|
const startTime = Date.now();
|
|
let ghostServer;
|
|
|
|
try {
|
|
// Config is the absolute first thing to do!
|
|
debug('Begin: Load config');
|
|
const config = require('./shared/config');
|
|
debug('End: Load config');
|
|
|
|
debug('Begin: Load version info');
|
|
const version = require('./server/lib/ghost-version');
|
|
config.set('version', version);
|
|
debug('End: Load version info');
|
|
|
|
debug('Begin: load server + minimal app');
|
|
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
|
|
|
|
// Get minimal application in maintenance mode
|
|
const rootApp = require('./app');
|
|
|
|
// Start server with minimal App
|
|
const GhostServer = require('./server/ghost-server');
|
|
ghostServer = new GhostServer();
|
|
await ghostServer.start(rootApp);
|
|
|
|
const logging = require('./shared/logging');
|
|
logging.info('Ghost server start', (Date.now() - startTime) / 1000 + 's');
|
|
debug('End: load server + minimal app');
|
|
|
|
debug('Begin: Get DB ready');
|
|
// Get the DB ready
|
|
await require('./db').ready();
|
|
debug('End: Get DB ready');
|
|
|
|
// Load Ghost with all its services
|
|
debug('Begin: Load Ghost Core Services');
|
|
await initCore({ghostServer});
|
|
|
|
const ghostApp = await initExpressApps({});
|
|
await initServices({config});
|
|
debug('End: Load Ghost Core Services');
|
|
|
|
// Mount the full Ghost app onto the minimal root app & disable maintenance mode
|
|
mountGhost(rootApp, ghostApp);
|
|
|
|
// Announce Server Readiness
|
|
logging.info('Ghost boot', (Date.now() - startTime) / 1000 + 's');
|
|
debug('boot announcing readiness');
|
|
GhostServer.announceServerReadiness();
|
|
} catch (error) {
|
|
const errors = require('@tryghost/errors');
|
|
// @TODO: fix these extra requires
|
|
const GhostServer = require('./server/ghost-server');
|
|
const logging = require('./shared/logging');
|
|
|
|
let serverStartError = error;
|
|
|
|
if (!errors.utils.isIgnitionError(serverStartError)) {
|
|
serverStartError = new errors.GhostError({message: serverStartError.message, err: serverStartError});
|
|
}
|
|
|
|
logging.error(serverStartError);
|
|
GhostServer.announceServerReadiness(serverStartError);
|
|
|
|
if (ghostServer) {
|
|
ghostServer.shutdown(2);
|
|
} else {
|
|
setTimeout(() => {
|
|
process.exit(2);
|
|
}, 100);
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = bootGhost;
|