DEV Community

Cover image for Installing Ghost Blogging Platform on Ubuntu 24.04
Sanskriti Harmukh for Vultr

Posted on with Aashish Chaurasiya Originally published at docs.vultr.com

Installing Ghost Blogging Platform on Ubuntu 24.04

Ghost is an open-source publishing platform with built-in newsletters, memberships, subscriptions, ActivityPub federation, and Tinybird-powered web analytics. This guide covers two install paths on Ubuntu 24.04: Ghost-CLI for a traditional host install, and Docker Compose for a containerized deployment with analytics.

Prerequisites: an Ubuntu 24.04 server, non-root sudo user, a domain A record (e.g. ghost.example.com).


Option A: Install with Ghost-CLI

Install Node.js

Ghost requires Node v22 LTS — check compatible versions before installing elsewhere.

$ curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
$ sudo -E bash nodesource_setup.sh
$ sudo apt install -y nodejs
$ node -v
Enter fullscreen mode Exit fullscreen mode

Install and Configure MySQL

$ sudo apt install -y mysql-server
$ mysql --version
$ sudo mysql_secure_installation
Enter fullscreen mode Exit fullscreen mode

Walk through the prompts: enable password validation (y), pick strong policy (2), remove anonymous users (y), restrict root to localhost (y), drop the test database (y), reload privileges (y).

$ sudo mysql
Enter fullscreen mode Exit fullscreen mode
mysql> CREATE DATABASE ghost_db;
mysql> CREATE USER 'ghostuser'@'localhost' IDENTIFIED BY 'Your_password2!';
mysql> GRANT ALL PRIVILEGES ON ghost_db.* TO 'ghostuser'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> EXIT;
Enter fullscreen mode Exit fullscreen mode

Install Nginx

$ sudo apt install -y nginx
$ sudo ufw allow 'Nginx Full'
$ sudo systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

Install Ghost

$ sudo npm install ghost-cli@latest -g
$ sudo mkdir -p /var/www/html/ghost
$ sudo chown $USER:$USER /var/www/html/ghost
$ sudo chmod 775 /var/www/html/ghost
$ cd /var/www/html/ghost
$ ghost install
Enter fullscreen mode Exit fullscreen mode

The installer prompts for:

  • Blog URL: https://ghost.example.com
  • MySQL hostname: localhost
  • MySQL username/password/database: from the setup above
  • Set up Nginx?: y
  • Set up SSL?: y (installs acme.sh)
  • Email for SSL: your address
  • Set up Systemd?: y
  • Start Ghost?: y

Manage the Config

$ nano /var/www/html/ghost/config.production.json
$ cd /var/www/html/ghost
$ ghost restart
Enter fullscreen mode Exit fullscreen mode

Or via systemd (replace ghost-example-com with your domain, dashed):

$ sudo systemctl restart ghost_ghost-example-com.service
$ sudo systemctl status ghost_ghost-example-com.service
Enter fullscreen mode Exit fullscreen mode

Update Ghost

$ cd /var/www/html/ghost
$ ghost backup
Enter fullscreen mode Exit fullscreen mode

ghost backup needs your sudo password and a staff access token (Settings → Staff → View Profile).

$ ghost update
Enter fullscreen mode Exit fullscreen mode

Or pin a version: ghost update VERSION. Expect brief downtime while migrations run.


Option B: Install with Docker Compose

Runs Ghost in containers with Caddy as the reverse proxy and optional Tinybird analytics.

Install Docker

Install Docker Engine + Compose plugin, then:

$ sudo usermod -aG docker $USER
$ newgrp docker
Enter fullscreen mode Exit fullscreen mode

Clone and Configure

$ git clone https://github.com/TryGhost/ghost-docker.git ~/ghost
$ cd ~/ghost
$ cp .env.example .env
$ cp caddy/Caddyfile.example caddy/Caddyfile
$ nano .env
Enter fullscreen mode Exit fullscreen mode

Set:

  • DOMAIN: ghost.example.com
  • DATABASE_ROOT_PASSWORD / DATABASE_PASSWORD: strong passwords
  • SMTP settings: your transactional email provider (SES, SendGrid, Mailgun)

Deploy

$ sudo ufw allow http
$ sudo ufw allow https
$ docker compose pull
$ docker compose up -d
$ docker compose ps
Enter fullscreen mode Exit fullscreen mode

Confirm every container shows Up/healthy.

Enable Web Analytics (Tinybird)

$ cd ~/ghost
$ docker compose run --rm tinybird-login
Enter fullscreen mode Exit fullscreen mode

Pick your region, copy the one-time code, complete auth in the browser.

$ docker compose run --rm tinybird-sync
$ docker compose run --rm tinybird-deploy
$ docker compose run --rm tinybird-login get-tokens
Enter fullscreen mode Exit fullscreen mode

Add the tokens to .env:

$ nano .env
Enter fullscreen mode Exit fullscreen mode
COMPOSE_PROFILES=analytics
TINYBIRD_API_URL=https://api.<region>.<provider>.tinybird.co
TINYBIRD_WORKSPACE_ID=your-workspace-id
TINYBIRD_ADMIN_TOKEN=your-admin-token
TINYBIRD_TRACKER_TOKEN=your-tracker-token
Enter fullscreen mode Exit fullscreen mode
$ docker compose pull
$ docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Enable ActivityPub Federation

$ nano .env
Enter fullscreen mode Exit fullscreen mode
COMPOSE_PROFILES=analytics,activitypub
ACTIVITYPUB_TARGET=activitypub:8080
Enter fullscreen mode Exit fullscreen mode

(Use COMPOSE_PROFILES=activitypub alone if you skipped analytics.)

$ docker compose pull
$ docker compose up -d --force-recreate ghost caddy
Enter fullscreen mode Exit fullscreen mode

Update via Docker

$ cd ~/ghost
$ docker compose pull
$ docker compose up -d
$ docker image prune -f
Enter fullscreen mode Exit fullscreen mode

If you changed .env or Caddy config: docker compose up -d --force-recreate ghost caddy.


Set Up Ghost

Visit https://ghost.example.com/ghost:

  1. Set site title, your name, admin email, and password.
  2. Click Create account & start publishing.
  3. From the admin panel: customize design/branding, write posts, configure membership tiers, add integrations, manage team members.

Next Steps

Ghost is running with TLS, either via Ghost-CLI's built-in setup or Caddy in the Docker Compose stack. From here:

  • Enable Tinybird analytics if you skipped it initially — it's a drop-in profile toggle
  • Turn on ActivityPub to federate your blog with Mastodon and other Fediverse readers
  • Set up scheduled ghost backup (CLI) or volume snapshots (Docker) before major updates

For the full guide, visit the original article on Vultr Docs.

Top comments (0)