Getting ready: prerequisites and decisions
Before you begin configuring Ghost, decide whether you want a managed service (Ghost(Pro)) or to self-host. Managed Ghost removes server maintenance and backups, while self-hosting gives you full control over infrastructure, updates and custom integrations. For self-hosting, a common choice is an ubuntu LTS server (20.04 or later) with at least 1 GB RAM for small blogs and 2 GB+ for production sites with members and payment features. You’ll also need a domain name, DNS control, and either mysql (recommended for production) or the default sqlite for small installations.
Install Ghost-cli and system dependencies
Install Node.js (LTS), nginx and Ghost-CLI. Using Ghost-CLI simplifies installation, service creation, nginx configuration and ssl via let’s encrypt. The sequence below shows commands for a fresh Ubuntu server; run them as a sudo user.
sudo apt update
sudo apt install -y nginx mysql-server curl unzip
curl -sL | sudo -E bash -
sudo apt install -y nodejs
sudo npm install -g ghost-cli@latest
After installing MySQL, create a database and user for Ghost if you plan to use MySQL in production. For a quick test you can use SQLite, but MySQL scales better and is recommended by Ghost for production.
sudo mysql -u root -p
CREATE DATABASE ghost_production;
CREATE USER 'ghost'@'localhost' IDENTIFIED BY 'your-password';
GRANT ALL PRIVILEGES ON ghost_production.* TO 'ghost'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Install Ghost using Ghost-CLI
Create a directory for Ghost, set ownership to the current user, then run the installer. The installer can configure Nginx and obtain a let’s encrypt certificate automatically if your domain is pointed at the server.
sudo mkdir -p /var/www/ghost
sudo chown $USER:$USER /var/www/ghost
cd /var/www/ghost
ghost install --db mysql --dbhost localhost --dbuser ghost --dbpass "your-password" --dbname ghost_production --url
The installer will prompt for confirmation and will set up a systemd service for Ghost, configure Nginx as a reverse proxy and enable https automatically if dns is correct. If you prefer to avoid interactive prompts you can add flags like –no-prompt and pass all required options on the command line.
Configure Nginx and HTTPS
Ghost-CLI typically writes an Nginx server block for you. If you need to manage Nginx yourself, ensure Nginx proxies requests to the Ghost process (usually listening on 2368 or a socket). Use strong tls settings and redirect HTTP to HTTPS. If you allowed Ghost-CLI to manage SSL, it will run certbot to obtain certificates. If you manage certificates manually or use Cloudflare, configure DNS to point the domain to your server and then obtain a certificate with certbot.
# Example Nginx snippet (reverse proxy)
server {
listen 80;
server_name example.com www.example.com;
return 301
}
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header host $http_host;
proxy_pass
}
}
Set up email (smtp) for signups and invites
To enable member signups, invites and transactional emails, configure an SMTP provider such as Mailgun, SendGrid, Postmark or any reliable SMTP server. Add the SMTP credentials to Ghost’s production configuration. You can set mail in config.production.json or via environment variables when using docker. Mail must be reliable; many common errors stem from incorrect credentials, blocked ports, or missing DNS records for the mail provider.
# Example config.production.json mail section
{
"mail": {
"transport": "SMTP",
"options": {
"host": "smtp.mailgun.org",
"port": 587,
"auth": {
"user": "postmaster@example.com",
"pass": "your-mailgun-password"
}
}
}
}
Essential configuration file: config.production.json
The config.production.json file is the main place for site-level settings when running Ghost directly (not in Docker). It contains URL, server settings, database, mail and logging. Keep the URL set to your canonical domain including https:// when using SSL. After any change to this file, restart Ghost using ghost restart or systemctl.
{
"url": "",
"server": {
"port": 2368,
"host": "127.0.0.1"
},
"database": {
"client": "mysql",
"connection": {
"host": "localhost",
"user": "ghost",
"password": "your-password",
"database": "ghost_production"
}
},
"mail": { ... },
"logging": {
"level": "info",
"rotation": { "enabled": true, "count": 5, "period": "1w" }
}
}
Docker installation option
If you prefer containers, Ghost provides an official Docker image. The Docker approach isolates Ghost from the host system, but you still need to manage persistence (content folder), backups and environment variables. Below is a simple docker-compose example that mounts content and sets the url and database to use SQLite for a single-container setup. For production, pair Ghost with a separate MySQL container or external database service.
version: '3'
services:
ghost:
image: ghost:latest
ports:
- "2368:2368"
environment:
url:
volumes:
- ./content:/var/lib/ghost/content
# Use an external MySQL or a separate container for production.
Themes, customization and Code Injection
Customize your site by installing a theme via the Ghost admin (Design > Upload theme) or by placing theme files directly into content/themes. After uploading a theme, activate it in the admin. Use Code Injection for site-wide header or footer scripts, and create custom templates or modify the theme’s templates if you need deeper changes. When working with themes locally, use the Ghost-CLI for development: run ghost start in a development environment or use the Ember/Handlebars workflow the themes expect.
Members, subscriptions and Stripe payments
Ghost supports members and paid subscriptions natively. To accept payments, connect Stripe from the Ghost admin: open Settings → Membership → Payment settings and enter Stripe API keys. Configure membership tiers and visibility settings, and ensure your site URL and webhooks are reachable from Stripe. Test payments in Stripe’s test mode before switching to live keys.
Backups and updates
Regular backups protect content and databases. For MySQL, use mysqldump; for SQLite, copy the SQLite file. Always include the content folder (images, theme files) in backups. Schedule automated backups with cron and store them offsite (S3, remote server). For updates, Ghost-CLI offers ghost update which safely upgrades Ghost and can also handle NPM dependencies; test updates in a staging environment if you have custom themes or integrations.
# Backup example (MySQL)
mysqldump -u ghost -p ghost_production > /backups/ghost_production_$(date +%F).sql
# Backup content
tar -czvf /backups/ghost_content_$(date +%F).tar.gz /var/www/ghost/content
Troubleshooting common issues
Permissions problems are common after manual file changes: ensure the Ghost installation directory is owned by the user running Ghost. If Ghost fails to start, check logs with ghost log in the installation directory or systemd logs via journalctl -u ghost_<your-site>. If mail isn’t sending, verify SMTP credentials, test connectivity to the mail host (telnet or openssl s_client) and confirm DNS records for SPF/DKIM as required by your provider. SSL issues usually come back to DNS not pointing to the server or rate limits from Let’s Encrypt if you requested certs too often during testing.
Security and maintenance tips
Lock down your server by keeping packages updated, running a firewall that allows only necessary ports (80, 443, and ssh on a custom port if desired), and disabling root ssh login. Use automatic security updates where appropriate and rotate secrets like database and SMTP passwords if you suspect exposure. If you run multiple sites on one server, consider using separate systemd services and directories per site to limit impact of issues.
Summary
Configuring Ghost involves choosing hosting, installing Ghost-CLI or using Docker, setting up Nginx and HTTPS, connecting SMTP for members, and customizing themes. Back up your database and content regularly and test changes in a staging environment before touching production. With the right configuration and maintenance routines, Ghost runs smoothly and provides a modern publishing platform that supports members and subscriptions out of the box.
FAQs
Can I run Ghost on a Shared Hosting provider?
shared hosting rarely gives the control Ghost needs (Node.js, process management, or custom ports). Use a vps, cloud instance or Ghost(Pro) for reliable production hosting.
Do I have to use MySQL?
No , Ghost can run with SQLite for small or development sites. For production deployments and better performance with backups and scaling, MySQL is recommended.
How do I enable HTTPS for my site?
Point your domain to the server and let Ghost-CLI obtain a Let’s Encrypt certificate during installation, or configure certbot/nginx manually. Ensure DNS is correct and that ports 80 and 443 are reachable.
What’s the easiest way to accept paid subscriptions?
Enable Members in Ghost and connect Stripe in the Ghost admin settings. Configure products (tiers) and test with Stripe test keys before going live with production keys.
How can I test configuration changes safely?
Use a staging server or a local development instance with a duplicate of your theme and database. Test theme updates, migrations and third-party integrations there before applying to production.
