1000 FAQs, 500 tutorials and explanatory videos. Here, there are only solutions!
Install Ghost on Infomaniak hosting
This guide helps you install Ghost on Infomaniak, an ideal platform for blogs (regular writing, editorial format) and content-focused publishing sites, such as Substack or Medium.
Based on Node.js and using Markdown for writing, Ghost stands out for its lightness, whereas WordPress, although more flexible and universal, is heavier.
For additional help, contact a partner or launch a free tender — also discover the role of the host.
Prerequisites
- Have installed a blank Node.js site on Infomaniak Web hosting.
- Create an SSH access.
- Create a database.
- Have a valid and functional email address (especially the forgotten password features).
Ghost Installation
To do this:
- Log in to the server via SSH (need help?).
- Navigate to the site directory by running the command “cd chemin-vers-le-site” (for example
cd sites/ghost.domain.xyz
). Enter the following command:
npx -p ghost-cli ghost install --check-empty=false
and enter the requested information (database host name, website URL, etc.).
Edit the
config.production.json
file to update the port and host parameters:"server": { "port": 3000, "host": "0.0.0.0" },
Specify the email information there as well:
"mail": { "transport": "SMTP", "options": { "service": "Infomaniak", "host": "mail.infomaniak.com", "port": 465, "auth": { "user": "<<email_username>>", "pass": "<<email_password>>" } }, "from": "<<email_address>>" },
Node.js Configuration
To run the application, go to the Node.js dashboard:
- Click here to access the management of your product on the Infomaniak Manager (need help?).
- Click directly on the name assigned to the relevant product.
- Click on Manage under Advanced Settings:
- Click on the Node.js tab to access the settings:
In the execution command field, enter:
npx -p ghost-cli ghost run
- Click the Save button at the bottom of the page.
- On the main page, click the Start or Restart button.
- Observe the logs showing the creation of the database and the start of the application:
- Then, go to your site's URL to start.
User/mail configuration
To create the first user, add /ghost
to the URL of your site (for example https://ghost.domain.xyz/ghost
) and follow the assistant.
You can also configure the "member portal support address": when new members want to register, the portal sends the double opt-in confirmation from a specific address. By default, this is the “noreply” address of your domain. To update it, navigate to “Settings”, “Membership”, “Portal Settings”, “Customize”, and “Account Page”:
Resolve a technical incompatibility between Ghost and MariaDB
There is a compatibility issue between Ghost and the MariaDB database. This results in this type of error:
[2025-05-26 12:54:28] ERROR "GET /ghost/api/admin/posts/6834625e35802b06f1496305/?formats=mobiledoc%2Clexical&include=tags%2Cauthors%2Cauthors.roles%2Cemail%2Ctiers%2Cnewsletter%2Ccount.conversions%2Ccount.clicks%2Csentiment%2Ccount.positive_feedback%2Ccount.negative_feedback" 400 27ms
Could not understand request.
Error ID:
8f2b0d90-3a30-11f0-a25f-fd9c83e1cf02
Error Code:
ER_BAD_FIELD_ERROR
----------------------------------------
Error: select `posts`.*, (with `k` as (select `member_id` from `members_subscription_created_events` where posts.id = members_subscription_created_events.attribution_id union select `member_id` from `members_created_events` where posts.id = members_created_events.attribution_id) select count(*) from `k`) as `count__conversions`, `posts`.*, (select count(distinct `members_click_events`.`member_id`) from `members_click_events` inner join `redirects` on `members_click_events`.`redirect_id` = `redirects`.`id` where posts.id = redirects.post_id) as `count__clicks`, `posts`.*, (select COALESCE(ROUND(AVG(score) * 100), 0) from `members_feedback` where posts.id = members_feedback.post_id) as `count__sentiment`, `posts`.*, (select count(*) from `members_feedback` where posts.id = members_feedback.post_id AND members_feedback.score = 0) as `count__negative_feedback`, `posts`.*, (select sum(`score`) from `members_feedback` where posts.id = members_feedback.post_id) as `count__positive_feedback` from `posts` where (`posts`.`type` = 'post' and `posts`.`status` in ('draft', 'published', 'scheduled', 'sent')) and `posts`.`id` = '2834125e33802b06e1433305' limit 1 - Unknown column 'posts.id' in 'where clause'
at Child.<anonymous> (/srv/customer/sites/ghost.domain.xyz/versions/5.120.2/core/server/models/base/plugins/crud.js:194:31)
at Packet.asError (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/packets/packet.js:740:17)
at Query.execute (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/commands/command.js:29:26)
at Connection.handlePacket (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/base/connection.js:475:34)
at PacketParser.onPacket (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/base/connection.js:93:12)
at PacketParser.executeStart (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/packet_parser.js:75:16)
at Socket.<anonymous> (/srv/customer/sites//versions/5.120.2/node_modules/mysql2/lib/base/connection.js:100:25)
at Socket.emit (node:events:518:28)
at addChunk (node:internal/streams/readable:561:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)
at Readable.push (node:internal/streams/readable:392:5)
at TCP.onStreamRead (node:internal/stream_base_commons:189:23)
Some SQL queries generated by Ghost, using common table expressions (CTE) nested in scalar subqueries, cause HTTP 400
errors when executed on MariaDB. These queries are valid in MySQL 8, which supports CTE in scalar subqueries, but not in MariaDB until version 10.6.
A patch is available to adapt Ghost's behavior and avoid these errors (refer to the official guide).
To use this patch, enter this command:
cd current
curl -L https://gist.githubusercontent.com/reneluria/8cbbfbc001e542c77d6d5887fbafe5d3/raw/65e0ce31753b4687d0eb67fc030734a35d3ffbad/ghost-post.patch | patch -p0