How to install Ghost with Apache HTTP Server on Ubuntu 20.04 (LTS)

Ghost is the world’s most popular open source headless Node.js CMS — it ships with a default admin client and front-end, but you can also swap them out with your own JAMstack.

Refresh your local software package database

sudo apt-get update

Install MySQL

sudo apt-get install mysql-server

To set a password, run

sudo mysql

Now update your user with this password
Replace 'password' with your password, but keep the quote marks!

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Now let's create the database

CREATE DATABASE blogdb;

Then exit MySQL

quit

Install Node.js

Add the NodeSource APT repository for Node 12

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

Install Node.js

sudo apt-get install -y nodejs

Install Ghost-CLI

sudo npm install ghost-cli@latest -g

Create a new user

Create a new user and follow prompts

adduser barrouh

Add user to superuser group to unlock admin privileges

usermod -aG sudo barrouh

Create a directory

Create a directory for your installation

sudo mkdir -p /var/www/ghost

Replace barrouh with the name of your user who will own this directory

sudo chown barrouh:barrouh /var/www/ghost

Set the correct permissions

sudo chmod 775 /var/www/ghost

Then navigate into it

cd /var/www/ghost

Login to your Ubuntu user

su - barrouh

Run the install process

curl -L -O https://ghost.org/zip/ghost-latest.zip
unzip ghost-latest.zip
rm ghost-latest.zip
npm install --production

Open config.production.json file

sudo nano /var/www/ghost/core/shared/config/env/config.production.json

Change the configuration to be like the following:

{
  "url": "http://blog.barrouh.com",
  "server": {
    "port": 8081,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "127.0.0.1",
      "user": "root",
      "password": "@@password",
      "database": "blogdb"
    }
  },
  "paths": {
    "contentPath": "content/"
  },
  "logging": {
    "level": "info",
    "rotation": {
      "enabled": true
    },
    "transports": [
      "file",
      "stdout"
    ]
  }
}

Start Ghost

npm start --production

Output:

> ghost@3.21.0 start /var/www/ghost
> node index

[2020-06-28 17:14:28] INFO Creating table: posts
[2020-06-28 17:14:28] INFO Creating table: posts_meta
[2020-06-28 17:14:29] INFO Creating table: users
[2020-06-28 17:14:29] INFO Creating table: posts_authors
[2020-06-28 17:14:29] INFO Creating table: roles
[2020-06-28 17:14:29] INFO Creating table: roles_users
[2020-06-28 17:14:29] INFO Creating table: permissions
[2020-06-28 17:14:29] INFO Creating table: permissions_users
[2020-06-28 17:14:29] INFO Creating table: permissions_roles
[2020-06-28 17:14:29] INFO Creating table: permissions_apps
[2020-06-28 17:14:29] INFO Creating table: settings
[2020-06-28 17:14:29] INFO Creating table: tags
[2020-06-28 17:14:29] INFO Creating table: posts_tags
[2020-06-28 17:14:29] INFO Creating table: apps
[2020-06-28 17:14:29] INFO Creating table: app_settings
[2020-06-28 17:14:30] INFO Creating table: app_fields
[2020-06-28 17:14:30] INFO Creating table: invites
[2020-06-28 17:14:30] INFO Creating table: brute
[2020-06-28 17:14:30] INFO Creating table: webhooks
[2020-06-28 17:14:30] INFO Creating table: sessions
[2020-06-28 17:14:30] INFO Creating table: integrations
[2020-06-28 17:14:30] INFO Creating table: api_keys
[2020-06-28 17:14:30] INFO Creating table: mobiledoc_revisions
[2020-06-28 17:14:30] INFO Creating table: members
[2020-06-28 17:14:30] INFO Creating table: labels
[2020-06-28 17:14:30] INFO Creating table: members_labels
[2020-06-28 17:14:30] INFO Creating table: members_stripe_customers
[2020-06-28 17:14:30] INFO Creating table: members_stripe_customers_subscriptions
[2020-06-28 17:14:30] INFO Creating table: actions
[2020-06-28 17:14:30] INFO Creating table: emails
[2020-06-28 17:14:30] INFO Model: Tag
[2020-06-28 17:14:30] INFO Model: Role
[2020-06-28 17:14:31] INFO Model: Permission
[2020-06-28 17:14:31] INFO Model: User
[2020-06-28 17:14:32] INFO Model: Post
[2020-06-28 17:14:32] INFO Model: Integration
[2020-06-28 17:14:32] INFO Relation: Role to Permission
[2020-06-28 17:14:32] INFO Relation: Post to Tag
[2020-06-28 17:14:32] INFO Relation: User to Role
[2020-06-28 17:14:36] INFO Ghost is running in production...
[2020-06-28 17:14:36] INFO Your site is now available on http://blog.barrouh.com
[2020-06-28 17:14:36] INFO Ctrl+C to shut down
[2020-06-28 17:14:36] INFO Ghost boot 9.634s

Create a systemd Service File

sudo nano /etc/systemd/system/ghost.service

Content:

[Unit]
Description=Ghost: Just a blogging platform
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/www/ghost
User=barrouh

ExecStart=/usr/bin/npm start --production
ExecStop=/usr/bin/npm stop --production

Restart=always

[Install]
WantedBy=multi-user.target

When you are finished, save and close the file.

Reload the systemd daemon so that it knows about our service file

sudo systemctl daemon-reload

For me i will use Ghost with Subdomain

I have already configured the subdomain blog.barrouh.com

How To Set Up Apache Virtual Host with Subdomain - Digitalocean

And i will use mod_proxy to link Apache with Ghost.

Here is an example for Tomcat:

Configuring Apache Tomcat With Apache HTTP Server - mod_proxy