← Back to TryGhost/Ghost

How to Deploy & Use TryGhost/Ghost

Ghost CMS Deployment & Usage Guide

1. Prerequisites

System Requirements

  • Node.js: Active LTS version (18.x or 20.x recommended)
  • Database:
    • Production: MySQL 8.0+ (or MariaDB 10.5+)
    • Development: SQLite3 (included) or MySQL
  • OS: Ubuntu 20.04/22.04 LTS (recommended for production), macOS/Linux/Windows (development)
  • Memory: Minimum 1GB RAM (2GB+ recommended for production)
  • Storage: 10GB+ available space

Required Tools

# Install Ghost CLI globally (required for production installs)
npm install ghost-cli -g

# Verify installation
ghost --version

# Required for production
sudo apt-get install nginx mysql-server  # Ubuntu/Debian
sudo systemctl enable nginx
sudo systemctl enable mysql

Accounts & API Keys (Optional)

  • Mailgun or SendGrid account (required for newsletters and member invites)
  • Stripe account (required for paid memberships/subscriptions)
  • Sentry DSN (optional, for error tracking in Portal)

2. Installation

Method A: Production Installation (Recommended)

Create a dedicated user and directory:

# Create user (do not run Ghost as root)
sudo adduser ghostuser
sudo usermod -aG sudo ghostuser
su - ghostuser

# Create installation directory
sudo mkdir -p /var/www/ghost
sudo chown ghostuser:ghostuser /var/www/ghost
cd /var/www/ghost

Run the installer:

ghost install

The installer will prompt for:

  • MySQL hostname (usually localhost)
  • MySQL username/password
  • Ghost database name
  • Site URL (https://yourdomain.com)
  • SSL configuration (Let's Encrypt)
  • Systemd setup (yes for production)

Method B: Local Development (From Source)

Clone the monorepo and install dependencies:

git clone https://github.com/TryGhost/Ghost.git
cd Ghost

# Install dependencies (monorepo uses yarn)
yarn install

# Setup default SQLite database
yarn setup

Method C: Local Quick Start (Ghost CLI)

mkdir ghost-local && cd ghost-local
ghost install local

3. Configuration

Configuration Files

Ghost uses JSON configuration files located at:

  • Production: /var/www/ghost/config.production.json
  • Development: config.development.json (in project root)

Essential Environment Variables

Ghost supports environment variable substitution using underscores:

# Database
database__client=mysql
database__connection__host=localhost
database__connection__user=ghost
database__connection__password=your_secure_password
database__connection__database=ghost_prod

# Server
url=https://yourdomain.com
server__port=2368
server__host=127.0.0.1

# Mail (required for newsletters)
mail__transport=SMTP
mail__options__service=Mailgun
mail__options__auth__user=postmaster@yourdomain.com
mail__options__auth__pass=your_mailgun_api_key

# Admin email
admin__fromAddress=noreply@yourdomain.com

Production Configuration Example

Create /var/www/ghost/config.production.json:

{
  "url": "https://yourdomain.com",
  "server": {
    "port": 2368,
    "host": "127.0.0.1"
  },
  "database": {
    "client": "mysql",
    "connection": {
      "host": "localhost",
      "user": "ghost",
      "password": "your_mysql_password",
      "database": "ghost_prod",
      "charset": "utf8mb4"
    }
  },
  "mail": {
    "transport": "SMTP",
    "options": {
      "service": "Mailgun",
      "auth": {
        "user": "postmaster@mg.yourdomain.com",
        "pass": "key-yourapikey"
      }
    }
  },
  "logging": {
    "transports": ["file", "stdout"]
  },
  "process": "systemd",
  "paths": {
    "contentPath": "/var/www/ghost/content"
  }
}

Membership & Stripe Configuration

Configure via Admin UI (Settings → Membership) or environment:

# Stripe (for paid subscriptions)
members__stripe__secret_key=sk_live_...
members__stripe__publishable_key=pk_live_...
members__stripe__webhook_secret=whsec_...

4. Build & Run

Development Mode (Source)

# Start Ghost in development with hot reload
yarn dev

# Access at http://localhost:2368/ghost/
# Default admin credentials created during setup

Production Mode (Ghost CLI)

# Start Ghost
ghost start

# Check status
ghost status

# View logs
ghost log -f

# Stop Ghost
ghost stop

# Restart after config changes
ghost restart

Manual Production Start (Without CLI)

cd /var/www/ghost
NODE_ENV=production node index.js

5. Deployment

Option 1: Ghost(Pro) Managed Hosting

The official managed service includes CDN, backups, SSL, and maintenance:

# No installation required
# Sign up at https://ghost.org/pricing/
# Provides automatic updates and 24/7 support

Option 2: Self-Hosted Ubuntu (Recommended)

  1. Follow Installation Method A above
  2. Configure Nginx reverse proxy (automatic with Ghost CLI)
  3. Enable SSL with Let's Encrypt (automatic with Ghost CLI)
  4. Configure firewall:
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable

Option 3: Docker (Unofficial)

version: '3.1'
services:
  ghost:
    image: ghost:5-alpine
    restart: always
    ports:
      - 8080:2368
    environment:
      database__client: mysql
      database__connection__host: db
      database__connection__user: root
      database__connection__password: example
      database__connection__database: ghost
      url: http://localhost:8080
    volumes:
      - ghost-data:/var/lib/ghost/content
  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
volumes:
  ghost-data:

Option 4: DigitalOcean 1-Click

DigitalOcean provides a Ghost droplet with pre-configured stack:

  • Select Ghost from Marketplace
  • Droplet automatically configures MySQL, Nginx, SSL, and Ghost
  • SSH in to complete setup via CLI prompts

6. Troubleshooting

Permission Denied Errors

Symptom: EACCES: permission denied during install Solution:

# Ensure correct ownership
sudo chown -R ghostuser:ghostuser /var/www/ghost
chmod 775 /var/www/ghost/content
# Never run ghost install with sudo

Database Connection Failed

Symptom: ER_ACCESS_DENIED_ERROR or ECONNREFUSED Solution:

# Verify MySQL is running
sudo systemctl status mysql

# Create database and user manually if needed
sudo mysql -u root
CREATE DATABASE ghost_prod;
CREATE USER 'ghost'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON ghost_prod.* TO 'ghost'@'localhost';
FLUSH PRIVILEGES;
EXIT;

Node Version Mismatch

Symptom: Ghost was built for Node.js version X but current version is Y Solution:

# Check supported versions
ghost doctor

# Use nvm to switch versions
nvm install 18
nvm use 18

Port Already in Use

Symptom: Port 2368 is already in use Solution:

# Find and kill process
sudo lsof -i :2368
sudo kill -9 <PID>

# Or change port in config
ghost config server.port 2369

SSL Certificate Issues

Symptom: HTTPS not working or certificate errors Solution:

# Reconfigure SSL
ghost setup ssl

# Check certificate expiry
ghost doctor

Portal/Membership Features Not Working

Symptom: Subscribe buttons not appearing or Stripe errors Solution:

  • Verify Stripe keys are set (test vs live mode)
  • Check mail configuration (required for member signup)
  • Ensure url in config matches actual domain (required for webhooks)
  • Check browser console for Sentry errors in Portal app

Update Failures

Symptom: Ghost update fails or site broken after update Solution:

# Rollback to previous version
ghost update --rollback

# Check for database migrations
ghost migrate

# Run doctor to check system
ghost doctor

Content Import/Export

Backup:

# Export content JSON via Admin UI (Labs → Export)
# Or backup database directly
mysqldump -u ghost -p ghost_prod > ghost_backup.sql

Restore:

# Import via Admin UI (Labs → Import)
# Or restore database
mysql -u ghost -p ghost_prod < ghost_backup.sql