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
Install and Configure MySQL
$ sudo apt install -y mysql-server
$ mysql --version
$ sudo mysql_secure_installation
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
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;
Install Nginx
$ sudo apt install -y nginx
$ sudo ufw allow 'Nginx Full'
$ sudo systemctl status nginx
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
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(installsacme.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
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
Update Ghost
$ cd /var/www/html/ghost
$ ghost backup
ghost backup needs your sudo password and a staff access token (Settings → Staff → View Profile).
$ ghost update
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
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
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
Confirm every container shows Up/healthy.
Enable Web Analytics (Tinybird)
$ cd ~/ghost
$ docker compose run --rm tinybird-login
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
Add the tokens to .env:
$ nano .env
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
$ docker compose pull
$ docker compose up -d
Enable ActivityPub Federation
$ nano .env
COMPOSE_PROFILES=analytics,activitypub
ACTIVITYPUB_TARGET=activitypub:8080
(Use COMPOSE_PROFILES=activitypub alone if you skipped analytics.)
$ docker compose pull
$ docker compose up -d --force-recreate ghost caddy
Update via Docker
$ cd ~/ghost
$ docker compose pull
$ docker compose up -d
$ docker image prune -f
If you changed .env or Caddy config: docker compose up -d --force-recreate ghost caddy.
Set Up Ghost
Visit https://ghost.example.com/ghost:
- Set site title, your name, admin email, and password.
- Click Create account & start publishing.
- 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)