Deploying Ghost CMS with DeployHQ: Automated Setup Guide

Devops & Infrastructure, Node, Open Source, Tutorials, and VPS

Deploying Ghost CMS with DeployHQ: Automated Setup Guide

Introduction

DeployHQ is a powerful deployment automation platform that streamlines the process of deploying web applications to your servers. In this guide, we'll show you how to leverage DeployHQ to automatically deploy and manage Ghost CMS on a Linode VPS, eliminating manual installation steps and enabling continuous deployment workflows.

Why Use DeployHQ for Ghost Deployment?

  • Automated Deployments: Push code changes and deploy automatically
  • Zero-Downtime Deployments: Keep your blog running during updates
  • Rollback Capabilities: Quickly revert to previous versions if needed
  • Multi-Environment Support: Manage staging and production environments
  • Build Pipeline Integration: Compile assets and run tests before deployment
  • Team Collaboration: Coordinate deployments across your team

Prerequisites

Before you begin, ensure you have:

  • A DeployHQ account (free trial available at deployHQ.com)
  • A Linode VPS with Ubuntu 20.04 LTS
  • SSH access to your server
  • A Git repository containing your Ghost installation or theme
  • A domain name (optional, but recommended)
  • Basic familiarity with Git version control

Part 1: Server Preparation

Step 1: Initial Server Setup

While DeployHQ automates deployment, you'll need to prepare your server environment once.

Connect to your Linode:

ssh root@your_server_ip

Update and secure your server:

# Update system packages
apt update && apt upgrade -y

# Create deployment user
adduser deploy
usermod -aG sudo deploy

# Configure firewall
apt install ufw
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

Step 2: Install Required Dependencies

# Install Node.js (Ghost requires Node.js 14.x or higher)
curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
sudo apt-get install -y nodejs

# Install MySQL
sudo apt install mysql-server
sudo mysql_secure_installation

# Install Nginx
sudo apt install nginx

# Install Ghost CLI
sudo npm install ghost-cli@latest -g

# Create Ghost directory
sudo mkdir -p /var/www/ghost
sudo chown deploy:deploy /var/www/ghost

Step 3: Configure MySQL Database

sudo mysql -u root -p

# Create database and user
CREATE DATABASE ghostdb;
CREATE USER 'ghostuser'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON ghostdb.* TO 'ghostuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Step 4: Initial Ghost Installation

# Switch to deploy user
su - deploy
cd /var/www/ghost

# Install Ghost (use production mode)
ghost install --db mysql --dbhost localhost --dbuser ghostuser --dbpass your_secure_password --dbname ghostdb --url https://yourdomain.com --process systemd

This creates the base Ghost installation that DeployHQ will manage.

Part 2: Setting Up DeployHQ

Step 5: Create a DeployHQ Project

  1. Log in to your DeployHQ account
  2. Click "New Project"
  3. Enter your project name (e.g., "Ghost Blog Production")
  4. Connect your Git repository:
    • GitHub
    • GitLab
    • Bitbucket
    • Or any Git repository URL
  5. Select the branch you want to deploy (usually main or production)

Step 6: Add Your Server to DeployHQ

  1. In your DeployHQ project, navigate to Servers & Groups

  2. Click "Add Server"

  3. Configure your server:

-   **Name**: Production Server
-   **Protocol**: SSH/SFTP
-   **Hostname**: Your Linode IP address
-   **Port**: 22
-   **Username**: deploy
-   **Authentication**: SSH Key (recommended) or Password
  1. Add your SSH key:
-   Generate a deployment key in DeployHQ
-   Add the public key to `/home/deploy/.ssh/authorized_keys` on your server
# On your server
mkdir -p /home/deploy/.ssh
nano /home/deploy/.ssh/authorized_keys
# Paste the DeployHQ public key, save and exit

chmod 700 /home/deploy/.ssh
chmod 600 /home/deploy/.ssh/authorized_keys

Step 7: Configure Deployment Settings

In DeployHQ, configure your deployment:

  1. Deployment Path: /var/www/ghost

  2. Deployment Mode: Choose one of:

-   **Normal**: Deploy all files
-   **Quick**: Only deploy changed files (recommended)
  1. Build Commands (if needed):

    npm install --production
    
  2. Deployment Commands: Execute after deployment:

    cd /var/www/ghost
    ghost restart
    

Step 8: Set Up Deployment Recipes

DeployHQ recipes are scripts that run before, during, or after deployment. Create recipes for Ghost-specific tasks:

Pre-deployment Recipe (Backup):

cd /var/www/ghost
ghost backup
mkdir -p /var/www/ghost-backups
mv content/data/ghost-backup-*.zip /var/www/ghost-backups/

Post-deployment Recipe (Restart Ghost):

cd /var/www/ghost
ghost restart
ghost ls

Part 3: Configuring Automated Deployments

Step 9: Enable Automatic Deployments

  1. In DeployHQ, go to Project SettingsAutomatic Deployments
  2. Enable "Deploy automatically when code is pushed"
  3. Choose your trigger:
    • Deploy on every push to main branch
    • Deploy only when tagged releases are created
    • Deploy on pull request merge

Step 10: Set Up Build Pipeline

Configure your build settings:

  1. Build Commands:

    npm ci --production
    npm run build # if you have custom build steps
    
  2. Files to Exclude (add to .deployignore):

    .git
    node_modules
    .ghost-cli
    .env.local
    *.log
    .DS_Store
    

Step 11: Configure Environment Variables

Store sensitive configuration in DeployHQ:

  1. Navigate to Config Files

  2. Create config.production.json:

    {
      "url": "https://yourdomain.com",
      "server": {
        "port": 2368,
        "host": "127.0.0.1"
      },
      "database": {
        "client": "mysql",
        "connection": {
          "host": "localhost",
          "user": "ghostuser",
          "password": "your_secure_password",
          "database": "ghostdb"
        }
      },
      "mail": {
        "transport": "SMTP",
        "options": {
          "service": "Mailgun",
          "auth": {
            "user": "your_mailgun_user",
            "pass": "your_mailgun_password"
          }
        }
      }
    }
    
  3. DeployHQ will securely deploy this file with each deployment

Part 4: Advanced DeployHQ Features

Step 12: Zero-Downtime Deployments

For production environments, enable zero-downtime deployments:

  1. Use Atomic Deployments:
-   DeployHQ creates a new release directory
-   Deploys to the new directory
-   Switches symlinks atomically
-   Old versions remain for quick rollback
  1. Configure symlinks:

    # Persistent directories that shouldn't be replaced
    content/images
    content/themes
    content/data    
    

Step 13: Set Up Staging Environment

Create a staging environment for testing:

  1. Add a second server in DeployHQ (your staging server)
  2. Create a deployment zone for the staging branch
  3. Test deployments on staging before promoting to production
  4. Use "Copy to Production" feature for controlled releases

Step 14: Configure Deployment Notifications

Stay informed about deployments:

  1. Navigate to Notifications in DeployHQ
  2. Configure integrations:
    • Slack notifications
    • Email alerts
    • Webhook calls
    • Discord notifications

Step 15: Implement Deployment Workflows

Set up approval workflows for critical deployments:

  1. Enable "Require Manual Approval" for production
  2. Set up deployment windows (e.g., only weekdays 9-5)
  3. Configure rollback policies

Part 5: Best Practices and Optimization

Deployment Strategy Recommendations

For Small Blogs:

  • Deploy automatically on every push to main
  • Keep 3-5 previous releases for rollback
  • Enable automatic backups before deployment

For Professional Publications:

  • Use staging → production workflow
  • Require manual approval for production deployments
  • Deploy during low-traffic windows
  • Keep 10+ previous releases

Performance Optimization

  1. Exclude Unnecessary Files: Use .deployignore to skip large files
  2. Parallel Deployments: Deploy to multiple servers simultaneously
  3. CDN Integration: Configure DeployHQ to purge CDN cache after deployment
  4. Asset Compilation: Build assets before deployment to reduce server load

Security Best Practices

  1. Use SSH Keys: Never use password authentication
  2. Rotate Keys Regularly: Update deployment keys quarterly
  3. Limit Permissions: Deploy user should only access necessary directories
  4. Audit Logs: Review DeployHQ deployment logs regularly
  5. Environment Variables: Store secrets in DeployHQ, never in Git

Troubleshooting Common Issues

Deployment Fails to Start

Check Connection:

# Test SSH connectivity
ssh deploy@your_server_ip

Verify Permissions:

ls -la /var/www/ghost
# Should be owned by deploy:deploy

Ghost Doesn't Restart

Check Ghost Status:

cd /var/www/ghost
ghost status
ghost doctor

Review Logs:

ghost log
# Or check DeployHQ deployment logs

File Permissions Issues

Fix Ownership:

sudo chown -R deploy:deploy /var/www/ghost
sudo chmod 755 /var/www/ghost

Continuous Integration Integration

Connect with GitHub Actions

Trigger DeployHQ deployments automatically from your CI pipeline using the official DeployHQ GitHub Action:

Step 1: Get Your DeployHQ Webhook URL

  1. In DeployHQ, navigate to your project
  2. Go to Automatic Deployments
  3. Copy your webhook URL

Step 2: Add GitHub Secrets

In your GitHub repository, add these secrets (Settings → Secrets → Actions):

  • DEPLOYHQ_WEBHOOK_URL: Your DeployHQ webhook URL
  • DEPLOYHQ_EMAIL: Your DeployHQ account email
  • REPO_CLONE_URL: Your repository clone URL (e.g., https://github.com/username/repo.git)
  • REPO_BRANCH (optional): Branch to deploy (defaults to main)
  • REPO_REVISION (optional): Specific commit to deploy (defaults to latest)

Step 3: Create Workflow File

Create .github/workflows/deploy.yml in your repository:

yaml

name: Deploy Ghost to Production

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Trigger DeployHQ deployment
        uses: deployhq/deployhq-action@main
        env:
          DEPLOYHQ_WEBHOOK_URL: ${{ secrets.DEPLOYHQ_WEBHOOK_URL }}
          DEPLOYHQ_EMAIL: ${{ secrets.DEPLOYHQ_EMAIL }}
          REPO_CLONE_URL: ${{ secrets.REPO_CLONE_URL }}
          REPO_BRANCH: ${{ secrets.REPO_BRANCH }}
          REPO_REVISION: 'latest'

Now every push to main will automatically trigger a deployment through DeployHQ!

Monitoring and Maintenance

Set Up Health Checks

Configure DeployHQ to verify deployments:

  1. Add a health check URL (e.g., https://yourdomain.com/ghost/api/v4/admin/site/)
  2. Set expected HTTP status code (200)
  3. Enable automatic rollback on health check failure

Automated Backups

Schedule regular backups through DeployHQ recipes:

#!/bin/bash
# Create backup before deployment
cd /var/www/ghost
timestamp=$(date +"%Y%m%d_%H%M%S")
ghost backup
mkdir -p /var/www/ghost-backups
mv content/data/ghost-backup-*.zip /var/www/ghost-backups/backup_$timestamp.zip

# Keep only last 7 days of backups
find /var/www/ghost-backups -name "backup_*.zip" -mtime +7 -delete

Conclusion

By leveraging DeployHQ for your Ghost CMS deployment, you've automated what was previously a complex manual process. Your blog now benefits from:

  • Rapid Deployments: Push code and deploy in minutes, not hours
  • Reduced Errors: Automated workflows eliminate manual mistakes
  • Easy Rollbacks: Revert to any previous version with one click
  • Team Collaboration: Multiple team members can deploy safely
  • Professional Workflow: Staging, testing, and production environments

Next Steps

  • Customize Your Theme: Develop and deploy theme changes automatically
  • Set Up Monitoring: Integrate with Uptime Robot or Pingdom
  • Configure CDN: Add Cloudflare or similar for better performance
  • Implement A/B Testing: Use multiple deployment zones for testing
  • Scale Horizontally: Add more servers to DeployHQ for high availability

Additional Resources


Need Help? The DeployHQ support team is available to assist with complex deployment scenarios and custom configurations.

Happy deploying!

A little bit about the author

Facundo | CTO | DeployHQ | Continuous Delivery & Software Engineering Leadership - As CTO at DeployHQ, Facundo leads the software engineering team, driving innovation in continuous delivery. Outside of work, he enjoys cycling and nature, accompanied by Bono 🐶.