Ghost CMS Installation on Linux

Ghost is a modern, open-source content management system designed for creators and professionals. It provides a streamlined publishing platform with a focus on simplicity, performance, and user experience. This guide walks through a complete installation of Ghost on a Linux server, including Node.js setup, MySQL database configuration, SSL certificates, and production deployment with systemd service management.

Table of Contents

Prerequisites

Before beginning the Ghost installation, ensure you have the following:

  • A VPS or dedicated server running Ubuntu 20.04 LTS or later
  • Root access or sudo privileges
  • A valid domain name pointing to your server
  • Minimum 2GB RAM (4GB+ recommended for production)
  • 10GB available disk space
  • Basic knowledge of Linux command line

Update your system packages to the latest versions before starting the installation process.

sudo apt update && sudo apt upgrade -y

System Requirements

Ghost has specific system requirements that must be met for optimal performance. The application requires Node.js 16.0 or higher, npm 7.0 or higher, and a compatible database system.

Check your current Node.js version if already installed:

node --version
npm --version

Verify system resources:

free -h
df -h

Node.js Installation

Node.js is the runtime environment required for Ghost. Install the latest LTS version from the NodeSource repository.

Add the NodeSource repository for Node.js 18 LTS:

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

Install Node.js and npm:

sudo apt install -y nodejs

Verify the installation:

node --version
npm --version

Install additional system dependencies:

sudo apt install -y build-essential python3

Configure npm to use the correct permissions for global packages:

mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

MySQL Database Setup

Ghost requires a database to store content. Install MySQL Server and create a dedicated Ghost database and user.

Install MySQL Server:

sudo apt install -y mysql-server

Start and enable MySQL service:

sudo systemctl start mysql
sudo systemctl enable mysql

Secure your MySQL installation:

sudo mysql_secure_installation

Create a database for Ghost:

sudo mysql -u root -p << EOF
CREATE DATABASE ghost;
CREATE USER 'ghost'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON ghost.* TO 'ghost'@'localhost';
FLUSH PRIVILEGES;
EXIT;
EOF

Test the database connection:

mysql -u ghost -p -h localhost
show databases;
exit;

Ghost Installation

Install Ghost CLI globally, which is the recommended way to install and manage Ghost:

npm install -g ghost-cli

Create a directory for Ghost installation:

sudo mkdir -p /var/www/ghost
sudo chown $USER:$USER /var/www/ghost
cd /var/www/ghost

Install Ghost using the interactive installer:

ghost install

The installer will prompt you for the following information:

  • Ghost version (press Enter for latest)
  • Database host: localhost
  • Database name: ghost
  • Database username: ghost
  • Database password: (enter the password you created)
  • Database port: 3306
  • Local port for Ghost: 2368
  • Subdomain: example.com (use your domain)
  • Enable HTTPS/SSL: Y (we'll configure SSL separately)
  • Setup Nginx: Y
  • Setup Systemd: Y

Monitor the installation progress and ensure all steps complete successfully. The installer will automatically configure Nginx and create a systemd service.

Start Ghost after installation:

cd /var/www/ghost
ghost start

Verify Ghost is running:

ghost status

Access the admin interface:

curl http://localhost:2368/admin

Nginx Reverse Proxy Configuration

Ghost CLI automatically configures Nginx, but you may need to verify or adjust the configuration. Check the Nginx configuration file:

sudo cat /etc/nginx/sites-available/example.com.conf

The configuration should look similar to this:

upstream ghost {
    server localhost:2368;
}

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

    location / {
        proxy_pass http://ghost;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Test Nginx configuration:

sudo nginx -t

Reload Nginx to apply changes:

sudo systemctl reload nginx

SSL Certificate Setup

Set up free SSL certificates using Let's Encrypt and Certbot. Ghost CLI usually handles this automatically during installation.

Install Certbot if not already installed:

sudo apt install -y certbot python3-certbot-nginx

Manually obtain an SSL certificate:

sudo certbot certonly --nginx -d example.com -d www.example.com

Update Nginx configuration to use HTTPS:

sudo nano /etc/nginx/sites-available/example.com.conf

Add or update the server block to redirect HTTP to HTTPS:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://ghost;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Test and reload Nginx:

sudo nginx -t
sudo systemctl reload nginx

Set up automatic certificate renewal:

sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Systemd Service Configuration

Ghost CLI automatically creates a systemd service. Verify the service configuration:

sudo systemctl status ghost_www.example.com

View the service file:

sudo cat /etc/systemd/system/ghost_www.example.com.service

The service should be configured to start Ghost automatically on system boot. Enable and start the service:

sudo systemctl enable ghost_www.example.com
sudo systemctl start ghost_www.example.com

Monitor the service logs:

sudo journalctl -u ghost_www.example.com -f

Check service status:

sudo systemctl status ghost_www.example.com

Post-Installation Configuration

Access the Ghost admin panel to complete the setup:

  1. Navigate to https://example.com/admin
  2. Create the admin account with username, email, and password
  3. Configure blog title and description
  4. Set up email configuration for notifications and alerts

Update Ghost configuration for production use:

cd /var/www/ghost
sudo nano .env

Key environment variables to verify:

NODE_ENV=production
GHOST_SECURITY__PASSWORD_MIN_LENGTH=12
GHOST_SECURITY__PASSWORD_MIN_PASSWORD_LENGTH=12

Configure email settings in the admin panel:

  1. Settings → General → Email
  2. Configure SMTP credentials for notifications

Verify Ghost is properly configured:

cd /var/www/ghost
ghost log

Backup and Maintenance

Implement a regular backup strategy for your Ghost installation and database. Create a backup script:

sudo nano /usr/local/bin/ghost-backup.sh

Add the following content:

#!/bin/bash

BACKUP_DIR="/backups/ghost"
GHOST_DIR="/var/www/ghost"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/ghost-backup-$DATE.tar.gz"

mkdir -p $BACKUP_DIR

# Backup Ghost files
tar -czf "$BACKUP_FILE" "$GHOST_DIR"

# Backup MySQL database
mysqldump -u ghost -p'StrongPassword123!' ghost | gzip > "$BACKUP_DIR/ghost-db-$DATE.sql.gz"

# Keep only last 30 days of backups
find $BACKUP_DIR -type f -mtime +30 -delete

echo "Backup completed: $BACKUP_FILE"

Make the script executable:

sudo chmod +x /usr/local/bin/ghost-backup.sh

Schedule daily backups using cron:

sudo crontab -e

Add the following line to run backup at 2 AM daily:

0 2 * * * /usr/local/bin/ghost-backup.sh >> /var/log/ghost-backup.log 2>&1

Update Ghost periodically:

cd /var/www/ghost
ghost update

Check for available updates:

cd /var/www/ghost
ghost update --check

Troubleshooting

If Ghost fails to start, check the logs:

cd /var/www/ghost
ghost log
tail -f /var/log/ghost.log

Verify database connectivity:

mysql -u ghost -p -h localhost ghost
show tables;
exit;

Check Node.js process:

ps aux | grep node

Restart Ghost if needed:

cd /var/www/ghost
ghost restart

Verify Nginx is properly configured:

sudo nginx -t
sudo systemctl status nginx

Check SSL certificate expiry:

openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates

Conclusion

Ghost is now fully installed and configured on your Linux server with Nginx reverse proxy, MySQL database, and SSL encryption. The systemd service ensures Ghost automatically starts on server reboot. Regular backups and updates keep your installation secure and reliable. Monitor the application logs regularly and maintain your database to ensure optimal performance. For advanced configurations, consult the official Ghost documentation at ghost.org.