To self-host Ghost CMS on Ubuntu 24.04, you need to prepare your server by installing Node.js (version 18 or 20 as of 2026-04), MySQL 8.x, and Nginx 1.27. The process involves creating a dedicated system user, setting up the database, configuring Nginx as a reverse proxy, and then installing Ghost using the Ghost-CLI tool, typically securing it with a free Let's Encrypt SSL certificate. This tutorial provides step-by-step instructions for a production-ready setup.

Prerequisites and Initial Server Setup

Before installing Ghost CMS, ensure you have a fresh Ubuntu 24.04 LTS server with root access. A Virtual Private Server (VPS) is ideal for self-hosting, offering the necessary control and resources. Providers such as Valebyte offer robust VPS hosting suitable for these workloads. For optimal security, it is highly recommended to perform an initial server hardening checklist for Ubuntu 24.04 before proceeding.

First, update your system's package list and upgrade existing packages to their latest versions. This ensures you're starting with a stable and secure base, addressing any known vulnerabilities as of 2026-04. After updating, install essential tools like curl and wget if they are not already present.

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget

Ghost CMS requires a dedicated system user with non-root privileges for security reasons. This user will own the Ghost installation directory and its processes. Create a new user, for example, ghost-user, and grant it sudo privileges temporarily to facilitate setup tasks.

sudo adduser ghost-user
sudo usermod -aG sudo ghost-user

Always perform administrative tasks as a non-root user with sudo privileges. This practice minimizes the risk of accidental system damage and improves overall server security.

Installing Core Dependencies: Node.js, MySQL, and Nginx

Ghost CMS relies on Node.js for its runtime environment, MySQL for database storage, and Nginx as a reverse proxy to serve the application and handle SSL. These are fundamental components for a functional Ghost installation.

Node.js Installation

Ghost CMS requires specific Node.js versions. As of 2026-04, Ghost generally supports Node.js 18.x and 20.x. Using a Node.js version manager like nvm (Node Version Manager) is recommended for flexibility, or you can use the official NodeSource PPA for system-wide installation. The NodeSource PPA provides up-to-date packages for Ubuntu systems, ensuring compatibility with the latest Ghost releases. For detailed instructions on Node.js installation, refer to the NodeSource documentation on GitHub.

To install Node.js 20.x via NodeSource PPA, execute the following commands:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Verify the Node.js and npm installations:

node -v
npm -v

You should see output similar to v20.12.2 for Node.js and 10.7.0 for npm, though specific versions may differ as updates are released.

MySQL 8.x Installation

Ghost CMS uses MySQL to store all blog content, user data, and settings. Ubuntu 24.04's default repositories include MySQL 8.x, which is compatible with Ghost. Install the MySQL server and client packages.

sudo apt install -y mysql-server

After installation, run the security script to improve the default MySQL setup. This script prompts you to set a root password, remove anonymous users, disallow remote root login, and remove the test database.

sudo mysql_secure_installation

Nginx Installation

Nginx will act as a reverse proxy, forwarding web requests to the Ghost Node.js application running on a local port. It also handles static file serving and SSL termination. Install Nginx from Ubuntu's repositories.

sudo apt install -y nginx
sudo ufw allow 'Nginx Full'

The ufw allow 'Nginx Full' command opens both HTTP (port 80) and HTTPS (port 443) firewall ports. If you are experiencing Nginx errors, check our Nginx 502 Bad Gateway Diagnostics Checklist.

Setting Up MySQL for Ghost CMS

Ghost CMS requires its own dedicated MySQL database and a user with specific permissions. This isolation enhances security and simplifies database management. Connect to your MySQL server as the root user.

sudo mysql -u root -p

You will be prompted for the MySQL root password you set during mysql_secure_installation. Once logged in, create the database and user. Replace ghost_db, ghost_user, and your_secure_password with your preferred values.

CREATE DATABASE ghost_db; 
CREATE USER 'ghost_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_secure_password';
GRANT ALL PRIVILEGES ON ghost_db.* TO 'ghost_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

The mysql_native_password plugin is often necessary for Ghost CLI to connect correctly, especially with newer MySQL versions that default to caching_sha2_2_password. Always choose a strong, unique password for your database user.

Installing Ghost-CLI and Ghost CMS

The Ghost-CLI is a command-line interface tool that simplifies the installation, configuration, and management of Ghost CMS. It handles many complex steps automatically.

Install Ghost-CLI

Install Ghost-CLI globally using npm, which ensures it's available from any directory on your server. This tool requires Node.js and npm to be installed correctly.

sudo npm install ghost-cli@latest -g

Create Ghost Installation Directory

Switch to the ghost-user and create a directory for your Ghost installation. It's common to place it under /var/www/. Replace yourdomain.com with your actual domain name.

sudo mkdir -p /var/www/yourdomain.com
sudo chown ghost-user:ghost-user /var/www/yourdomain.com
sudo chmod 775 /var/www/yourdomain.com
su -l ghost-user
cd /var/www/yourdomain.com

The su -l ghost-user command logs you in as ghost-user with its environment, which is crucial for subsequent Ghost CLI commands to run with correct permissions. If you need advanced database tuning, explore MySQL slow query log analysis.

Run Ghost Installation

Now, run the Ghost installation command. The Ghost-CLI will guide you through the setup process, asking for your domain, MySQL details, and whether to set up Nginx and SSL automatically. For this tutorial, we will let Ghost-CLI handle Nginx and SSL for simplicity, but you can also configure them manually.

  1. Start the installation:
    ghost install
    
  2. Enter your blog's URL: This should be your public domain, e.g., https://yourdomain.com.
  3. Configure MySQL: Provide the database host (localhost), user (ghost_user), password (your_secure_password), and database name (ghost_db) you created earlier.
  4. Set up Nginx: Confirm you want Ghost-CLI to set up Nginx. This will create a configuration file in /etc/nginx/sites-available/ and enable it.
  5. Set up SSL: Confirm you want Ghost-CLI to set up SSL with Let's Encrypt. You'll need to provide an email address for certificate renewals.
  6. Systemd setup: Confirm you want Ghost to run as a systemd service. This ensures Ghost starts automatically on boot and runs reliably.
  7. Start Ghost: Confirm you want to start Ghost now.

If the installation completes successfully, you will see a message indicating Ghost is running. You can then access your Ghost blog at the URL you provided.

Configuring Nginx and SSL with Let's Encrypt

When Ghost-CLI sets up Nginx and SSL, it automates creating a server block and obtaining a Let's Encrypt certificate. It's still beneficial to understand the underlying configuration.

Nginx Configuration Review

Ghost-CLI creates a configuration file for your domain in /etc/nginx/sites-available/ and symlinks it to /etc/nginx/sites-enabled/. The configuration typically includes a reverse proxy directive to forward requests to Ghost's Node.js process, which usually runs on port 2368 locally.

An example Nginx configuration might look like this:

server {
    listen 80;
    listen [::]:80;

    server_name yourdomain.com www.yourdomain.com;
    root /var/www/yourdomain.com/system/nginx-root;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_pass http://127.0.0.1:2368;
    }

    location ~ /\. {
        deny all;
    }

    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
    include /etc/nginx/snippets/ssl-params.conf;

}

This configuration redirects HTTP traffic to HTTPS and serves your Ghost blog securely. The proxy_pass directive is crucial for directing traffic to the Ghost application. For more advanced Nginx configurations, consult the official Nginx documentation.

Let's Encrypt SSL Certificates

Ghost-CLI uses Certbot to obtain and renew Let's Encrypt SSL certificates. These certificates provide free, automated SSL for your domain. Certbot also sets up a cron job or systemd timer to automatically renew your certificates before they expire, typically every 90 days. You can test the renewal process manually:

sudo certbot renew --dry-run

If the dry run is successful, your certificates will renew automatically. For detailed information on Certbot and Let's Encrypt, visit the Let's Encrypt documentation.

Post-Installation and Maintenance

After successfully installing Ghost CMS, several ongoing tasks ensure your blog remains secure, performant, and up-to-date. Regular maintenance is key to the longevity of your self-hosted platform.

Accessing Your Ghost Admin Panel

Navigate to https://yourdomain.com/ghost/ in your web browser. You'll be prompted to create your administrator account, set your blog title, and invite team members. This is where you'll manage all your content, themes, and settings.

Updating Ghost CMS

Ghost releases updates frequently, bringing new features and security patches. To update your Ghost installation, log in as your ghost-user, navigate to your Ghost installation directory, and run the update command.

su -l ghost-user
cd /var/www/yourdomain.com
ghost update

The Ghost-CLI handles database migrations, file updates, and restarting the Ghost service automatically. Always back up your database and content before performing major updates.

Backups and Recovery

Regular backups are critical for any self-hosted application. Ghost CMS provides a built-in export feature for your content. For a full server backup, consider tools like rsync or a dedicated backup service, especially if your VPS provider offers snapshot capabilities. A comprehensive backup strategy includes both database dumps and a copy of your Ghost content directory.

# Export Ghost content via admin panel or Ghost-CLI (requires Ghost-CLI v5.0.0+ for direct export)
# Example for database backup:
sudo mysqldump -u ghost_user -p ghost_db > ~/ghost_db_backup_$(date +%F).sql

Store backups in a secure, off-site location. This protects your data against server failures or accidental deletion. If you're running on a VPS, configuring IPv6 on your VPS can also be a good step for future-proofing your server's network capabilities.

Monitoring and Logging

Monitor your server's resources (CPU, RAM, disk I/O) to ensure optimal performance. Tools like htop, top, and journalctl can provide insights into system activity and Ghost's logs. The Ghost application logs are typically found within your Ghost installation directory under /content/logs/.