I’m trying to update an old installation of ghost on my Ubuntu 18.04. My old version was using:
Ghost-CLI version: 1.15.3
Ghost version: 3.42.0
mysql Ver 14.14 Distrib 5.7.33
Nodejs: v12.14.0
I initially upgraded my Node.js to version 14, as the previous version was incompatible with both ghost update v3
and the newer Ghost CLI version. Following that, I upgraded MySQL to version 8.0.33, adjusted collations like the tutorial suggested and made sure that it was working before continuing. Afterward, I further upgraded Node.js to version 16.20.2 and proceeded with the Ghost update process. Firstly, I updated Ghost CLI to version 1.24.2, and then upgraded Ghost to version 5.60.0.
When I run ghost start
I get this error:
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: “Error occurred while executing the following migration: 23-regenerate-posts-html.js”
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: Error ID:
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: 300
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: ----------------------------------------
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: TypeError: Cannot read properties of undefined (reading ‘replace’)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at /var/www/ghost/versions/5.60.0/node_modules/knex-migrator/lib/index.js:1032:19
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at prepareText (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/utils/dom.js:9:15)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at createTextNode (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/utils/dom.js:13:29)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at Renderer.renderMarkersOnElement (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderers/0-3.js:190:69)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at Renderer.renderMarkupSection (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderers/0-3.js:474:12)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at Renderer.renderSection (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderers/0-3.js:139:23)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at /var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderers/0-3.js:103:31
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at Array.forEach ()
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at Renderer.render (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderers/0-3.js:102:21)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at RendererFactory.render (/var/www/ghost/versions/5.60.0/node_modules/mobiledoc-dom-renderer/dist/commonjs/mobiledoc-dom-renderer/renderer-factory.js:109:71)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at MobiledocHtmlRenderer.render (/var/www/ghost/versions/5.60.0/node_modules/@tryghost/kg-mobiledoc-html-renderer/lib/MobiledocHtmlRenderer.js:116:35)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at /var/www/ghost/versions/5.60.0/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js:42:61
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: at processTicksAndRejections (node:internal/process/task_queues:96:5)
Aug 28 21:26:22 ip-172-31-36-55 node[27633]:
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: [2023-08-28 21:26:22] WARN Ghost is shutting down
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: [2023-08-28 21:26:22] WARN Ghost has shut down
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: [2023-08-28 21:26:22] WARN Your site is now offline
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: [2023-08-28 21:26:22] WARN Ghost was running for a few seconds
Aug 28 21:26:22 ip-172-31-36-55 node[27633]: [2023-08-28 21:26:22] INFO Bootstrap client was closed.
Aug 28 21:26:22 ip-172-31-36-55 systemd[1]: Stopping Ghost systemd service for blog: admin-gazillions-com…
The knex-migrator function that throws the errors is:
KnexMigrator.prototype._migrateTo = function _migrateTo(options) {
options = options || {};
let self = this,
version = options.version,
hooks = options.hooks || {},
only = options.only || null,
skip = options.skip || null,
subfolder = this.subfolder,
skippedTasks = [],
tasks = [];
if (version !== 'init') {
tasks = utils.readTasks(path.join(self.migrationPath, subfolder, version));
} else {
try {
tasks = utils.readTasks(path.join(self.migrationPath, version));
} catch (err) {
if (err.code === 'MIGRATION_PATH') {
tasks = [];
} else {
throw err;
}
}
}
if (only !== null) {
debug('only: ' + only);
tasks = [tasks[only - 1]];
} else if (skip !== null) {
debug('skip: ' + skip);
tasks.splice(skip - 1, 1);
}
debug('Migrate: ' + version + ' with ' + tasks.length + ' tasks.');
debug('Tasks: ' + JSON.stringify(tasks));
return Promise.each(tasks, function executeTask(task) {
return self._beforeEach({
task: task.name,
version: version
}).then(function () {
if (hooks.beforeEach) {
return hooks.beforeEach({
connection: self.connection
});
}
}).then(function () {
debug('Running up: ' + task.name);
if (task.config && task.config.transaction) {
return database.createTransaction(self.connection, function (txn) {
return task.up({
transacting: txn
});
});
}
return task.up({
connection: self.connection
});
}).then(function () {
if (hooks.afterEach) {
return hooks.afterEach({
connection: self.connection
});
}
}).then(function () {
return self._afterEach({
task: task,
version: version
});
}).catch(function (err) {
if (err instanceof errors.MigrationExistsError) {
debug('Skipping:' + task.name);
skippedTasks.push(task.name);
return Promise.resolve();
}
/**
* @NOTE: When your database encoding is set to utf8mb4 and you set a field length > 191 characters,
* MySQL will throw an error, BUT it won't roll back the changes, because ALTER/CREATE table commands are
* implicit commands.
*
* https://bugs.mysql.com/bug.php?id=28727
* https://github.com/TryGhost/knex-migrator/issues/51
*/
if (err.code === 'ER_TOO_LONG_KEY') {
let match = err.message.match(/`\w+`/g);
let table = match[0];
let field = match[2];
throw new errors.MigrationScriptError({
message: 'Field length of %field% in %table% is too long!'.replace('%field%', field).replace('%table%', table),
context: 'This usually happens if your database encoding is utf8mb4.\n' +
'All unique fields and indexes must be lower than 191 characters.\n' +
'Please correct your field length and reset your database with `yarn knex-migrator reset`.\n',
help: 'Read more here: https://github.com/TryGhost/knex-migrator/issues/51\n',
err: err
});
}
throw new errors.MigrationScriptError({
message: err.message,
help: 'Error occurred while executing the following migration: ' + task.name,
context: task,
err: err
});
});
}).then(function () {
return {
skippedTasks: skippedTasks
};
});
};
I have checked my tables, and my collations are right, all set to utf8mb4_0900_ai_ci. What else could be the problem?