How to deploy & self-host Ghost on DigitalOcean

How to deploy & self-host Ghost on DigitalOcean

We may earn an affiliate commission through purchases made from our guides and tutorials.

Here’s the straight path to getting Ghost running on DigitalOcean. I’ll show you two clean ways: the super-fast 1-Click image, and the rock-solid manual install that gives you full control. I’ll also cover mail, SSL, backups, updates, and the gotchas that trip people up.

If you’re wondering whether Ghost is still worth self-hosting: yes. It’s lean, modern, and production-ready. I’ve been around enough CMS setups to know that “simple” usually hides a mess. Ghost is the rare one that actually means it.

What you’ll get by the end

  • A production Ghost instance behind NGINX, with HTTPS from Let’s Encrypt
  • Systemd keeping Ghost alive across reboots
  • MySQL 8 configured the way Ghost expects it (no socket auth shenanigans)
  • A sane update/backup routine you can live with

Ghost’s current stack: Ubuntu 22.04/24.04, NGINX, MySQL 8, and Node 22 LTS. Don’t improvise on versions; Ghost v6+ requires Node 22 LTS and won’t support older LTS lines anymore.

Option A — DigitalOcean Marketplace (fastest)

If you want the quickest path from zero to live, spin up the Ghost 1-Click Droplet and finish the CLI prompts. It wires up NGINX, SSL, systemd, and MySQL for you.

High-level flow

  1. Create the Ghost 1-Click Droplet (choose at least 1GB RAM; I prefer 2GB for headroom).
  2. Point your domain’s A record to the Droplet IP. Do this before running Ghost’s setup, so SSL can provision.
  3. SSH in and follow the prompts to complete ghost install (the image drops you right into it).

If the 1-Click image is temporarily out of date (it happens), skip to Option B and do the manual install—it’s just as clean, and you’ll be current on Node/CLI.

Option B — Manual install with Ghost-CLI (my default)

This takes a few more minutes but gives you a clean, reproducible setup on any Ubuntu 22.04/24.04 Droplet.

1) Create your Droplet & point DNS

  • Pick Ubuntu 22.04 or 24.04, 1–2GB RAM.
  • In your DNS, add an A record for your domain to the Droplet’s IPv4. Do this now; we’ll need it for SSL. Ghost’s official install assumes the DNS is already in place.

2) SSH in and create a non-root sudo user

Ghost’s own docs warn not to name the user ghost (it conflicts with the CLI).

ssh root@YOUR_DROPLET_IP

adduser deploy
usermod -aG sudo deploy
su - deploy

3) Update base packages

sudo apt-get update
sudo apt-get upgrade -y

4) Install NGINX and open the firewall

Ghost expects NGINX (not Apache). The CLI will generate site configs for you.

sudo apt-get install -y nginx
sudo ufw allow 'Nginx Full' || true

5) Install MySQL 8 and switch root to password auth

Ubuntu ships MySQL with socket auth for root; Ghost needs password auth.

sudo apt-get install -y mysql-server

sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' BY 'REPLACE_ME_STRONG';
FLUSH PRIVILEGES;
exit

6) Install Node 22 LTS (Nodesource method Ghost recommends)

Don’t use distro Node, nvm on servers, or random PPAs.

sudo apt-get install -y ca-certificates curl gnupg
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg

NODE_MAJOR=22
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | \
  sudo tee /etc/apt/sources.list.d/nodesource.list

sudo apt-get update
sudo apt-get install -y nodejs
node -v

7) Install Ghost-CLI globally

This is the supported way to install/operate Ghost in production.

sudo npm install -g ghost-cli@latest
ghost --version

8) Create the web root and set permissions

sudo mkdir -p /var/www/ghost
sudo chown deploy:deploy /var/www/ghost
sudo chmod 775 /var/www/ghost
cd /var/www/ghost

9) Run the installer (wires up NGINX, SSL, MySQL, systemd)

ghost install

You’ll be prompted for:

  • Blog URL – use https://yourdomain.com (not an IP).
  • MySQLlocalhost, user root, and the password you set above; the CLI can create a scoped DB user for you (say yes).
  • NGINX – let the CLI create the config.
  • SSL – say yes; Let’s Encrypt will be provisioned automatically.
  • systemd – yes.
    When it asks to start Ghost, say yes.

Now visit https://yourdomain.com/ghost to create your admin account.

Optional but sensible on small Droplets: add swap

1GB RAM is the minimum; adding a small swap file prevents OOM kills during updates or theme builds.

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Email: transactional vs newsletters (know the difference)

  • Transactional mail (sign-in links, staff invites) can use any SMTP (Postmark, Sendgrid, SES, your own). Configure via Ghost config/CLI.
  • Newsletter sending requires a bulk-mail API Ghost supports. As of now, Ghost supports Mailgun for bulk newsletters. If you don’t plan to send newsletters by email, you can skip Mailgun entirely and just publish on the site.

You can also set SMTP directly with ghost config flags (see CLI docs for options).

Day-2 Ops: updates, logs, SSL renewals, backups

Update Ghost safely

cd /var/www/ghost
ghost update

If Node LTS ever bumps again, update Node first, then force-reinstall your current Ghost to rebuild native deps:

# Update Node to a supported version per docs, then:
ghost version
ghost update --force

Ghost’s Node version policy and step-by-step upgrade notes are here; Ghost v6+ requires Node 22 LTS.

Check health & logs

ghost ls
ghost doctor
ghost log

CLI commands and flags are documented in detail.

Renew or (re)issue SSL

ghost setup ssl

Ghost-CLI manages Let’s Encrypt for you via its setup stages.

Backups (two easy layers)

  • Quick site backup (CLI): creates a zip with data you’ll need to restore.
  • Content export (inside Admin): JSON export of posts/tags/pages/settings; good for migrations and “belt-and-suspenders”.
cd /var/www/ghost
ghost backup

(If you rely on comments or custom extras, complement with DB dumps and content/ copies. The forum docs and admin export pages explain what’s included/excluded and how to handle migrations cleanly.)

Common pitfalls (so you don’t waste a Saturday)

  • Wrong Node version. If you see “Unsupported version of Node,” you’re not on 22 LTS. Fix Node with the Nodesource steps above, then ghost update --force. The supported-versions matrix is explicit.
  • DNS not pointed before SSL. The ACME challenge will fail if your A record isn’t live. Point DNS first, wait a minute, then run ghost install/ghost setup ssl.
  • MySQL root using socket auth. Set mysql_native_password exactly as shown earlier. Otherwise Ghost can’t auth.
  • Low RAM during updates. Add a small swap; it’s cheap stability.
  • 1-Click image lagging behind. If the marketplace image ever ships with an outdated Node/CLI, manual install avoids the dead-end.

Bonus: moving, staging, and recovery

  • Migrate/restore by doing a clean install on the new box, importing your content export, copying content/ assets, restoring theme(s), and switching DNS.
  • Rollback a bad update quickly:
cd /var/www/ghost
ghost update --rollback

CLI has a built-in rollback if an update misbehaves.

Sanity checklist (quick pass)

  • Ubuntu 22.04/24.04 ✅
  • Node 22 LTS
  • MySQL 8 with password auth ✅
  • NGINX via Ghost-CLI config ✅
  • Let’s Encrypt via Ghost-CLI ✅
  • systemd enabled ✅
  • DNS A record in place ✅
  • Backups tested once ✅

If you follow those exactly, this setup will run for years with minimal drama—and when you do need to update, it’ll be routine.

Was this helpful?

Thanks for your feedback!
Alex is the resident editor and oversees all of the guides published. His past work and experience include Colorlib, Stack Diary, Hostvix, and working with a number of editorial publications. He has been wrangling code and publishing his findings about it since the early 2000s.

Leave a comment

Your email address will not be published. Required fields are marked *