How to set up the Ghost blogging platform on Ubuntu 24.04 Server

The Ghost blogging platform is an excellent choice for creating modern, attractive blogs. Written in Node.js, this open-source software offers a lightweight and faster alternative to comprehensive content management systems like WordPress. This tutorial provides a guide to installing Ghost on an Ubuntu 24.04 server.

Ghost Features

As of late 2024, Ghost boasts a range of features designed to streamline the blogging experience:

  • A Markdown-based editor for quick post creation.
  • Simple content management tools.
  • Collaborative editing capabilities.
  • Scheduled publishing options.
  • Built-in analytics for tracking performance.
  • SEO optimization with semantic markup, permalinks, XML sitemaps, and metadata control.
  • Integrated AMP (Accelerated Mobile Pages) support.
  • Full RSS feeds, email subscription forms, and Slack webhook integration.
  • A marketplace with free and premium themes.
  • A default theme, Casper, with dark mode support.
  • Cross-platform desktop app for Linux, Mac, and Windows.
  • An official Ghost Migrator WordPress plugin for easy migration from WordPress.

While managed hosting is available from the Ghost foundation, this guide focuses on creating a self-hosted Ghost blog on an Ubuntu server.

Requirements

To run Ghost, you’ll need a server with at least 1GB of RAM.

You’ll also need a domain name.

Note: This guide assumes you’re installing Ghost with a sudo user on Ubuntu. For best results, follow the tutorial with a sudo user, not root. To add a sudo user, run:

sudo adduser username
sudo adduser username sudo

Then, switch to the new user:

su - username

Step 1: Update Ubuntu.

If your server hasn’t been updated recently, run the following command to update existing software packages.

sudo apt update; sudo apt upgrade -y

Step 2: Install Node.js on Ubuntu.

Ghost requires the LTS version of Node.js. While the latest version is v22.x, Ghost is currently more compatible with Node.js v18.x. Add the NodeSource repository using the command below.

curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -

Then install Node.js.

sudo apt install -y nodejs

Check the Node version.

node -v

Sample output:

v18.20.2

Check npm version:

npm -v

Sample output:

10.5.0

Step 3: Install MariaDB Database Server.

Ghost supports MySQL and MariaDB. MariaDB is a drop-in replacement for MySQL. Install the MariaDB database server:

sudo apt install mariadb-server mariadb-client

After installation, the MariaDB server should start automatically. Use systemctl to check its status:

systemctl status mariadb

Sample output:

● mariadb.service - MariaDB 10.11.7 database server
   Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2024-05-04 11:13:27 UTC; 21s ago
     Docs: man:mysqld(8)
           https://mariadb.com/kb/en/library/systemd/
 Main PID: 3473 (mysqld)
   Status: "Taking your SQL requests now..."
    Tasks: 27 (limit: 505)
   CGroup: /system.slice/mariadb.service
           └─3473 /usr/sbin/mysqld

If it’s not running, start it with this command:

sudo systemctl start mariadb

Enable MariaDB to automatically start at system boot time:

sudo systemctl enable mariadb

Run the post-installation security script:

sudo mysql_secure_installation
  • When prompted for the MariaDB root password, press Enter as the root password isn’t yet set.
  • Don’t switch to unix_socket authentication because MariaDB is already using unix_socket authentication.
  • Don’t change the root password because you don’t need to set a root password when using unix_socket authentication.

Next, you can press Enter to answer all remaining questions. This will remove anonymous users, disable remote root login, and remove the test database. This step is a basic requirement for MariaDB database security. (Note that Y is capitalized, meaning it is the default answer.)

Check MariaDB server version information:

mariadb --version

Output:

mariadb Ver 15.1 Distrib 10.11.7-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper

Step 4: Create a Database and User for Ghost.

Log in to the MariaDB console and create a database and user for Ghost:

sudo mariadb -u root

Create a database for Ghost:

create database ghost;

Create a database user for Ghost and grant all privileges of the ghost database to the user:

grant all privileges on ghost.* to ghost@localhost identified by 'ghost_password';

Flush the privileges table for the changes to take effect, and then log out of the MariaDB console:

flush privileges;

exit;

Step 5: Install Nginx Web Server.

Ghost uses the Nginx web server, so run the following command to install it from the default Ubuntu repository:

sudo apt install nginx

If you are using the UFW firewall, then you also need to open ports 80 and 443:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Step 6: Create A Record For Your Blog Domain Name.

Before installing Ghost, create a DNS A record for your blog domain name. The A record points your domain name to the IP address of your Ubuntu server.

Step 7: Install Ghost on Ubuntu Server.

Install Ghost-CLI:

sudo npm install ghost-cli@latest -g

Create a directory (/var/www/ghost/) for Ghost:

sudo mkdir -p /var/www/ghost/

Grant permissions to your user account. Replace username with your real username:

sudo apt install acl

sudo setfacl -R -m u:username:rwx /var/www/ghost/

sudo chmod 775 /var/www/ghost

Change the working directory to /var/www/ghost/ and install Ghost:

cd /var/www/ghost/

ghost install

This command will check if your server environment meets the requirements and install all dependencies.

During the installation, you will be asked to enter your blog URL and the MariaDB database name and user credentials you created in step 4.

? Enter your blog URL: https://yourdomain.com
? Enter your MySQL hostname: localhost
? Enter your MySQL username: ghost
? Enter your MySQL password: ghost_password
? Enter your Ghost database name: ghost

A ghost system user will be created automatically.

It’s recommended that you accept to set up Nginx and SSL so that your blog will be available via the secure HTTPS protocol.

Also, accept to set up the Systemd service so you will be able to start, stop, or restart Ghost easily.

If you encounter the “Nginx is not installed. Skipping Nginx setup” error, please refer to the troubleshooting section on manually creating the Nginx config file for Ghost.

Once Ghost is installed successfully, go to https://yourdomain.com/ghost to complete the setup. First, create an account.

Then, invite staff users to your Ghost blog, or do it later.

Step 8: Edit the Nginx Config File.

By default, the Nginx configuration file for Ghost contains one domain name. If you want Nginx to serve both the www domain and the non-www domain, edit the configuration file:

sudo nano /etc/nginx/sites-enabled/yourdomain.com.conf

Find the following line:

server_name yourdomain.com;

Add the www domain:

server_name yourdomain.com www.yourdomain.com;

Save and close the file. Then, delete the /etc/nginx/sites-enabled/yourdomain.com-ssl.conf file:

sudo rm /etc/nginx/sites-enabled/yourdomain.com-ssl.conf

Install the Certbot Let’s Encrypt client:

sudo apt install certbot python3-certbot-nginx

Obtain an SSL certificate for both the www domain and the non-www domain:

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d yourdomain.com,www.yourdomain.com

Restart Nginx:

sudo systemctl restart nginx

Step 9: Set Up Email Notification.

To send emails from your Ghost blog (for password resetting, inviting staff users, member signup, etc.), configure the SMTP settings. There are two options:

  • Use an SMTP relay service (easier).
  • Set up your own email server (takes more time).

SMTP Relay

If you would like to use an SMTP relay service, once that’s done, edit the Ghost configuration file:

sudo nano /var/www/ghost/config.production.json

By default, the mail settings are as follows:

"mail": {
   "transport": "Direct"
},

Change it to:

  "mail": {
    "transport": "Sendmail",
    "from": "notifications@yourdomain.com"
  },

Save and close the file. Then, restart Ghost via the systemd service:

sudo systemctl restart ghost_yourdomain-com.service

Now your Ghost blog should be able to send emails.

Use Your Own Email Server

If you would like to use your own email server, once you have it, edit the Ghost configuration file:

sudo nano /var/www/ghost/config.production.json

By default the mail settings are as follows:

"mail": {
   "transport": "Direct"
},

Change it to use SMTP:

"mail": {
    "transport": "SMTP",
    "from": "notifications@yourdomain.com",
    "options": {
        "service": "yourdomain.com",
        "host": "mail.yourdomain.com",
        "port": 465,
        "secureConnection": true,
        "auth": {
            "user": "notifications@yourdomain.com",
            "pass": "the_email_account_password"
        }
    }
},

Note that Ghost doesn’t support port 587 for SMTP. Save and close the file. Then restart Ghost via the systemd service:

sudo systemctl restart ghost_yourdomain-com.service

Now your Ghost blog should be able to send emails.

Troubleshooting: How to Manually Set Up Nginx for Ghost

If during the installation you encounter the “Nginx is not installed. Skipping Nginx setup” error, then manually create the Nginx config file:

sudo nano /etc/nginx/conf.d/ghost.conf

Add the following lines in this file:

server {
    listen [::]:80;
    listen 80;
    server_name example.com www.example.com;

    root /var/www/ghost/;

    access_log /var/log/nginx/ghost.access.log;
    error_log /var/log/nginx/ghost.error.log;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header HOST $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://127.0.0.1:2368;
        proxy_redirect off;
    }

    # allow Let's Encrypt checks on .well-known without proxying
    location ~ /.well-known {
        allow all;
    }
}

Save and close the file. Then, test Nginx configurations:

sudo nginx -t

If the test is successful, reload Nginx:

sudo systemctl reload nginx

To obtain a valid TLS certificate, install the Certbot Let’s Encrypt client:

sudo apt install certbot python3-certbot-nginx

Obtain a TLS certificate for both the www domain and the non-www domain:

sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d example.com,www.example.com

Restart Nginx:

sudo systemctl restart nginx

This tutorial provided the steps to install Ghost on an Ubuntu 24.04 server, so you can create a modern blog.