Deploy Ghost on a VPS in Minutes
Launch a self-hosted Ghost publication on a VPS you fully control. Ghost-CLI wires up Node.js, MySQL, an NGINX reverse proxy, and Let's Encrypt SSL in a single guided session — no managed plan, no cut of your revenue.
What you can do with self-hosted Ghost on a VPS
Ghost is an open-source headless CMS built for publishing and newsletters. Run it on a VPS, and you own the whole stack — editor, memberships and email delivery — instead of paying a monthly fee for managed hosting.
Run your own publication and newsletter
Keep 100% of your subscription revenue
Own the full stack with root access
Deliver newsletters with Mailgun
Ship fast, custom themes
Scale on your own terms
Choose a VPS plan for Ghost
Ghost, MySQL, and NGINX use around 1.2 GB at rest, so RAM is the spec that matters, and Start VPS is the minimum that fits comfortably. Begin with a Start VPS for a personal blog or small newsletter; move to Medium VPS once it's an active publication with a growing subscriber list. Every plan includes one dedicated IPv4 address, free weekly backups, KVM, and full root/SSH access. RAM, drive, and other specs are scalable later. One caveat on the Start plan: outbound SMTP ports are blocked by default — open a support ticket to enable email before configuring your newsletter (a KYC check may apply).
- 40 CountriesFrom$10.19 / 1 month$9.68 with is*smart
- Xeon 2x2.20 GHz CPU
- 2 Gb RAM
- 30GB SSD Drive
- 3 Tb Bandwidth
- 40 CountriesFrom$21.24 / 1 month$20.18 with is*smart
- Xeon 3x2.20 GHz CPU
- 4 Gb RAM
- 40GB SSD Drive
- Unmetered Bandwidth
- 40 CountriesFrom$33.99 / 1 month$32.29 with is*smart
- Xeon 4x2.20 GHz CPU
- 8 Gb RAM
- 50GB SSD Drive
- Unmetered Bandwidth
Boost Your VPS Server Resources
Check out how you can change the configuration of your VPS. You can purchase additional drive space, increase CPU performance, add RAM, and take advantage of additional services without having to switch to a new plan.
How to deploy Ghost on a VPS
A full install of Ghost 6.x on a fresh Ubuntu 24.04 server takes about 15 minutes. Point a DNS A-record at your VPS IP first — Let's Encrypt needs DNS resolving before it can issue your SSL certificate. Hardening and email setup are listed as next steps at the end. The steps below cover the core install; for the full walkthrough with every command and screenshot, see our complete guide to installing Ghost on a VPS in the blog.
Step 01 — Create a non-root sudo user
Ghost-CLI refuses to run as root. Don't name the user ghost — it clashes with the system user Ghost-CLI creates during setup.
adduser ghostadminusermod -aG sudo ghostadminStep 02 — Install dependencies and open the firewall
Install NGINX, MySQL, and the packages for Node.js, then allow web traffic:
su - ghostadminsudo apt-get update && sudo apt-get upgrade -ysudo apt-get install -y nginx mysql-server ca-certificates curl gnupgsudo ufw allow 'Nginx Full'sudo ufw allow OpenSSHsudo ufw enableSwitch MySQL's root user to password auth, which Ghost requires:
sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH 'mysql_native_password' BY 'your_secure_password'; FLUSH PRIVILEGES;"Step 03 — Install Node.js 22 LTS
Ghost 6.x runs on Node.js v22 only. Install it from NodeSource:
sudo mkdir -p /etc/apt/keyringscurl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpgecho "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.listsudo apt-get update && sudo apt-get install -y nodejsStep 04 — Install Ghost-CLI
Install the official installer globally as root, then switch back to your user:
exitnpm install ghost-cli@latest -gsu - ghostadminStep 05 — Create the install directory and run the installer
Ghost lives in /var/www/ghost with your user as owner:
sudo mkdir -p /var/www/ghostsudo chown ghostadmin:ghostadmin /var/www/ghostsudo chmod 775 /var/www/ghostcd /var/www/ghostghost installAnswer the wizard with your blog URL (full https:// domain), MySQL details, and yes to the NGINX, SSL and systemd prompts. Ghost-CLI configures the reverse proxy, requests a Let's Encrypt certificate and starts Ghost as a systemd service.
Step 06 — Go live and confirm the ports
Your admin panel is now at https://yourdomain.com/ghost/. Ports 80 and 443 are public via NGINX; Ghost (2368) and MySQL (3306) stay bound to localhost, so no extra firewall rules are needed. Open the admin URL to create your account and publish your first post.
Next steps (before production): harden SSH, connect Mailgun for newsletters, set up monitoring, and run ghost backup before every ghost update — rollback a bad update with ghost update --rollback.
Common issues
- Ghost-CLI refuses to run as root. That's by design — Ghost-CLI won't install under the root account. Create a non-root sudo user first and run the install from there. Don't name that user ghost either, as it collides with the system user Ghost-CLI creates during setup.
- SSL step is skipped during install. If Ghost-CLI prints "SSL certs cannot be generated for IP addresses, skipping," you ran the install against an IP instead of a domain. Point a DNS A-record at your VPS before installing and enter the full https:// domain as your blog URL — Let's Encrypt needs DNS resolving to issue the certificate.
- Ghost can't connect to MySQL. On Ubuntu, MySQL 8's root user defaults to socket-based authentication, which Ghost can't use. Switch it to password auth with mysql_native_password, and use those credentials in the install wizard.
- Newsletter emails don't send. Outbound SMTP is blocked by default on the Start plan, so Mailgun delivery fails until it's enabled. Open a support ticket to unblock the SMTP ports (a KYC check may apply), then add your Mailgun API key under Settings → Newsletters.
- Install fails on the wrong Node.js version. Ghost 6.x runs on Node.js v22 LTS only and will refuse to install on Node 18 or 20. Install v22 from NodeSource and confirm with node --version before running ghost install. Note also that MySQL 8 is required — MariaDB isn't supported for production.