
Ghost is an open-source publishing platform designed for bloggers, journalists, and content creators. It provides built-in newsletter functionality, membership management, and subscription features. Recent versions support ActivityPub federation for interaction with decentralized social networks and include web analytics through Tinybird integration.
This article explains how to install Ghost Blogging Platform on Ubuntu 24.04 using two methods: Ghost-CLI for a traditional installation and Docker Compose for containerized deployments with analytics capabilities.
Prerequisites
Before you begin, ensure you:
- Have access to an Ubuntu 24.04 based server as a non-root user with
sudoprivileges. - Create a domain A record pointing to the instance's public IP address, such as
ghost.example.com.
The CLI method installs Ghost directly on the host system using Ghost-CLI. This requires you to install Node.js, MySQL, and Nginx as dependencies before installing Ghost.
Install Node.js
Ghost is compatible with Node v22 LTS. You can check the list of compatible Node versions for Ghost at the official documentation.
Download and run the NodeSource setup script to install Node.js v22 LTS.
console$ curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh $ sudo -E bash nodesource_setup.sh $ sudo apt install -y nodejs
Verify the installed Node.js version.
console$ node -v
Output:
v22.21.0
Install and Configure MySQL
Install the MySQL Server.
console$ sudo apt install -y mysql-server
MySQL starts automatically and runs as a service.
Verify the MySQL installation.
console$ mysql --version
Your output should be similar to the one below.
mysql Ver 8.0.43-0ubuntu0.24.04.2 for Linux on x86_64 ((Ubuntu))Secure the MySQL installation.
console$ sudo mysql_secure_installation
Follow the interactive prompts to improve MySQL security. The root account uses the
auth_socketplugin by default, which authenticates based on the system user and does not require a separate password.- VALIDATE Password: Enter
yto enable password validation for new database users. - Password Validation Policy: Enter
2for strong password requirements (uppercase, lowercase, numbers, special characters). - Remove anonymous users: Enter
yto remove anonymous access. - Disallow root login remotely: Enter
yto restrict root access to localhost only. - Remove test database: Enter
yto delete the test database. - Reload privilege tables: Enter
yto apply changes immediately.
- VALIDATE Password: Enter
Log in to the MySQL console.
console$ sudo mysql
Create a database, user, and grant privileges.
sqlmysql> 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 Web Server
Install Nginx.
console$ sudo apt install -y nginx
Allow HTTP and HTTPS traffic through the firewall.
console$ sudo ufw allow 'Nginx Full'
Verify Nginx is running.
console$ sudo systemctl status nginx
Install Ghost
Install the Ghost-CLI package globally.
console$ sudo npm install ghost-cli@latest -g
Create a directory for the Ghost installation.
console$ sudo mkdir -p /var/www/html/ghost
Set ownership to the current user.
console$ sudo chown $USER:$USER /var/www/html/ghost
Set directory permissions.
console$ sudo chmod 775 /var/www/html/ghost
Navigate to the Ghost directory.
console$ cd /var/www/html/ghost
Run the Ghost installation process.
console$ ghost install
The installer prompts for configuration details. Provide the following information:
- Enter your blog URL: Your domain with HTTPS, e.g.,
https://ghost.example.com - Enter your MySQL hostname:
localhost - Enter your MySQL username: The username created earlier (e.g.,
ghostuser) - Enter your MySQL password: The password set earlier (e.g.,
Your_password2!) - Enter your Ghost database name: The database created earlier (e.g.,
ghost_db) - Do you wish to set up Nginx?: Enter
yto configure Nginx automatically - Do you wish to set up SSL?: Enter
yto installacme.shfor SSL certificate management - Enter your email (For SSL Certificates): A valid email address for certificate notifications
- Do you wish to set up Systemd?: Enter
yto create a systemd service for Ghost - Do you want to start Ghost?: Enter
yto start Ghost immediately
- Enter your blog URL: Your domain with HTTPS, e.g.,
Manage Ghost Configuration
To update any of the parameters, edit the configuration file below..
console$ nano /var/www/html/ghost/config.production.json
After changing the configuration, restart Ghost.
console$ cd /var/www/html/ghost $ ghost restart
Alternatively, restart and view the status of Ghost using systemd. Replace
ghost-example-comwith your domain name.console$ sudo systemctl restart ghost_ghost-example-com.service $ sudo systemctl status ghost_ghost-example-com.service
From the output, verify that the service is running.
Update Ghost
Navigate to the Ghost installation directory.
console$ cd /var/www/html/ghost
Create a backup before updating. This command prompts for your sudo password and staff access token. You can find the staff access token under Settings > Staff > View Profile.
console$ ghost backup
Update Ghost to the latest version.
console$ ghost update
Ghost-CLI handles database migrations and applies all required changes, which may result in brief downtime.
To update to a specific version, replace
VERSIONwith the desired release.console$ ghost update VERSION
The Docker Compose method deploys Ghost in containers, providing better isolation and built-in support for web analytics through Tinybird.
Install Docker
Follow the How to Install Docker on Ubuntu 24.04 article to install Docker Engine and Docker Compose plugin, then add your user to the docker group.
$ sudo usermod -aG docker $USER
$ newgrp docker
Clone the Ghost Docker Repository
Clone the repository and navigate to it.
console$ git clone https://github.com/TryGhost/ghost-docker.git ~/ghost $ cd ~/ghost
Configure Ghost
Create configuration files from the provided templates.
console$ cp .env.example .env $ cp caddy/Caddyfile.example caddy/Caddyfile
Edit the
.envfile to configure Ghost.console$ nano .env
Update the following variables:
- DOMAIN: Your Ghost domain (e.g.,
ghost.example.com) - DATABASE_ROOT_PASSWORD: A strong password for the MySQL root user
- DATABASE_PASSWORD: A strong password for the Ghost database user
- SMTP Settings: Configure your SMTP credentials for a transactional email provider such as Amazon SES, SendGrid, or Mailgun.
Save and close the file.
- DOMAIN: Your Ghost domain (e.g.,
Deploy Ghost
Allow HTTP and HTTPS traffic through the firewall.
console$ sudo ufw allow http $ sudo ufw allow https
Pull the Docker images defined in the compose file.
console$ docker compose pull
Start the Ghost containers in detached mode.
console$ docker compose up -d
Verify that all containers are running.
console$ docker compose ps
Confirm that the STATUS column shows each container as Up and healthy.
Enable Web Analytics
Create a Tinybird account and set up a workspace.
Navigate to the Ghost directory.
console$ cd ~/ghost
Authenticate with Tinybird using the Docker container.
console$ docker compose run --rm tinybird-login
Select your Tinybird workspace region from the list. The command generates a one-time code and a URL. Open the URL in a browser, log in to Tinybird, select your workspace, and enter the provided code to complete authentication.
» No region detected, select one from the list below: [1] europe-west2 (gcp) (https://cloud.tinybird.co/gcp/europe-west2) [2] europe-west3 (gcp) (https://cloud.tinybird.co/gcp/europe-west3) [3] us-east4 (gcp) (https://cloud.tinybird.co/gcp/us-east4) [4] us-east-1 (aws) (https://cloud.tinybird.co/aws/us-east-1) [5] us-west-2 (aws) (https://cloud.tinybird.co/aws/us-west-2) [6] eu-central-1 (aws) (https://cloud.tinybird.co/aws/eu-central-1) [7] eu-west-1 (aws) (https://cloud.tinybird.co/aws/eu-west-1) [8] northamerica-northeast2 (gcp) (https://cloud.tinybird.co/gcp/northamerica-northeast2) [0] Cancel Use region [1]: 1 First, copy your one-time code: YM2L-0Z51 Press [Enter] to continue in the browser... » Opening browser for authentication... If browser does not open, please open the following URL manually: https://cloud.tinybird.co/api/cli-login?apiHost=https%3A%2F%2Fapi.europe-west2.gcp.tinybird.co&code=YM2L0Z51&method=code Workspace: ghosttutorial User: admin@example.com Host: https://api.europe-west2.gcp.tinybird.co ✓ Authentication successful!Synchronize Tinybird configuration files to the local volume.
console$ docker compose run --rm tinybird-sync
Deploy the Tinybird configuration, which creates Tinybird datasources, pipes, and API endpoints. This process may take several minutes.
console$ docker compose run --rm tinybird-deploy
Generate Tinybird API tokens.
console$ docker compose run --rm tinybird-login get-tokens
Update the
.envfile with Tinybird configuration.console$ nano .env
Add or update the Tinybird section with the values from the previous command:
iniCOMPOSE_PROFILES=analytics TINYBIRD_API_URL=https://api.europe-west2.gcp.tinybird.co TINYBIRD_WORKSPACE_ID=bd3356c1-fb2b-4620-9a62-caa5ccf6c02b TINYBIRD_ADMIN_TOKEN=p.eyJ1IjogImJkMzM1NmMxLWZi... TINYBIRD_TRACKER_TOKEN=p.eyJ1IjogImJkMzM1NmMxLWZi...
Replace the values with your actual tokens.
Save and close the file.
Pull updated Docker images and restart Ghost with analytics enabled.
console$ docker compose pull $ docker compose up -d
Enable ActivityPub Federation
Edit the
.envfile to enable the ActivityPub profile.console$ nano .env
Update the
COMPOSE_PROFILESvariable to includeactivitypub.iniCOMPOSE_PROFILES=analytics,activitypub
If you haven't enabled analytics, use:
iniCOMPOSE_PROFILES=activitypub
Uncomment the
ACTIVITYPUB_TARGETvariable.iniACTIVITYPUB_TARGET=activitypub:8080
Save and close the file.
Pull the ActivityPub container and recreate Ghost and Caddy.
console$ docker compose pull $ docker compose up -d --force-recreate ghost caddy
Update Ghost Using Docker
Navigate to the Ghost directory.
console$ cd ~/ghost
Pull the latest Docker images.
console$ docker compose pull
Restart containers with the new images.
console$ docker compose up -d
Remove unused Docker images to free disk space.
console$ docker image prune -f
If you modified
.envor Caddy configuration, force container recreation.console$ docker compose up -d --force-recreate ghost caddy
Access and Configure Ghost
Navigate to the Ghost admin panel at
https://ghost.example.com/ghost.
Complete the initial setup form with the following details:
- Site title: Your blog or publication name
- Full name: Your name (displayed as the author)
- Email address: Admin account email
- Password: A strong password for the admin account
Click Create account & start publishing to complete setup.
After setup, access the admin panel at
https://ghost.example.com/ghostto:- Customize site design and branding
- Create content and manage posts
- Configure membership and subscription tiers
- Set up integrations and custom code injection
- Manage team members and permissions
Conclusion
You have successfully installed Ghost on Ubuntu 24.04 using either Ghost-CLI for traditional deployments or Docker Compose for containerized environments. Both methods provide a production-ready Ghost installation with SSL certificates, automated backups (CLI method), and optional web analytics through Tinybird integration. Ghost is now ready for content creation, newsletter distribution, and membership management.