Panduan lengkap install Ghost CMS di Ubuntu dengan Nginx, MySQL, dan SSL Let's Encrypt hingga Ghost dapat diakses lewat HTTPS.
Halo, Kawan Belajar! Kalau kamu sedang mencari platform blogging yang modern, cepat, dan ramah SEO tanpa harus pusing dengan plugin tak berujung seperti di WordPress, Ghost bisa jadi jawabannya. Dibangun di atas Node.js, Ghost hadir dengan editor berbasis Markdown, fitur membership dan newsletter yang sudah terintegrasi, serta performa yang terbukti jauh lebih ringan. Tidak heran jika Ghost semakin digemari oleh penulis, developer, hingga kreator konten profesional.
Di panduan ini, kita akan membahas cara install Ghost di Ubuntu 24.04 LTS menggunakan Nginx sebagai reverse proxy, MySQL 8.0 sebagai database, dan SSL dari Let's Encrypt untuk keamanan koneksi. Ghost punya tool CLI resminya sendiri yang akan mengotomasi sebagian besar proses ini, jadi prosesnya tidak serumit yang dibayangkan.
Ghost adalah CMS (Content Management System) open source yang fokus pada blogging dan penerbitan konten digital. Berbeda dari platform berbasis PHP, Ghost dibangun sepenuhnya dengan Node.js sehingga lebih ringan dan responsif. Ghost cocok untuk blog pribadi, media online, newsletter berkala, hingga platform membership berbayar dengan sistem monetisasi bawaan.
Sebelum mulai, siapkan hal-hal berikut:
| Kebutuhan | Spesifikasi |
|---|---|
| Sistem operasi | Ubuntu 22.04 LTS atau 24.04 LTS |
| RAM | Minimal 1 GB (rekomendasi 2 GB ke atas) |
| Domain | Domain aktif yang sudah diarahkan ke IP server |
| Akses server | SSH sebagai user non-root dengan hak sudo |
| Port terbuka | 80 (HTTP) dan 443 (HTTPS) |
sudo. Jika kamu masih login sebagai root, ikuti Langkah 1 untuk membuat user baru sebelum melanjutkan.
Jika kamu saat ini login sebagai root, buat user baru dengan hak sudo terlebih dahulu:
adduser ghostuser
usermod -aG sudo ghostuser
Kemudian beralih ke user tersebut:
su - ghostuser
Setelah itu, update dan upgrade paket sistem:
sudo apt update && sudo apt upgrade -y
Nginx akan berfungsi sebagai reverse proxy yang meneruskan request dari port 80 dan 443 ke Ghost yang berjalan secara lokal. Ghost-CLI akan mengonfigurasi Nginx secara otomatis nanti, jadi yang perlu kamu lakukan sekarang hanyalah install Nginx di Ubuntu terlebih dahulu.
sudo apt install nginx -y
Aktifkan Nginx dan pastikan layanannya berjalan saat server reboot:
sudo systemctl start nginx
sudo systemctl enable nginx
Verifikasi status Nginx:
sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since ...
Main PID: 1234 (nginx)
Selanjutnya, buka port HTTP dan HTTPS di firewall. Jika kamu ingin memahami lebih dalam cara kerja konfigurasi UFW di Ubuntu, tersedia panduan terpisah — tapi untuk keperluan instalasi Ghost, tiga perintah berikut sudah mencakup semua yang dibutuhkan:
sudo ufw allow 'Nginx Full'
sudo ufw allow OpenSSH
sudo ufw enable
Verifikasi bahwa port 80 dan 443 sudah benar-benar terbuka:
sudo ufw status
Pastikan baris Nginx Full muncul dengan status ALLOW di output sebelum melanjutkan ke langkah berikutnya.
Ghost menggunakan MySQL sebagai database utamanya. Panduan lengkap tersedia di artikel install MySQL 8.0 di Ubuntu, tapi untuk kebutuhan instalasi Ghost, jalankan perintah berikut:
sudo apt install mysql-server -y
Jalankan skrip konfigurasi keamanan bawaan MySQL:
sudo mysql_secure_installation
Ikuti promptnya. Kamu akan diminta mengatur plugin validasi password, menghapus user anonim, menonaktifkan remote root login, dan menghapus database uji coba. Jawab Y untuk semua opsi keamanan tersebut.
Setelah selesai, masuk ke shell MySQL sebagai root:
sudo mysql -u root
Buat database dan user khusus untuk Ghost. Ganti ghost_db, ghost_user, dan StrongPassword123! sesuai kebutuhan kamu:
CREATE DATABASE ghost_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'ghost_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON ghost_db.* TO 'ghost_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Node.js 22 LTS (Jod) adalah versi minimum yang didukung oleh Ghost saat ini. Dukungan untuk versi-versi lama seperti v18 dan v20 sudah resmi dihentikan, jadi pastikan kamu menginstal versi yang tepat. Di sini kita fokus pada versi minimum yang dibutuhkan untuk Ghost.
Tambahkan repositori NodeSource:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
Install Node.js:
sudo apt install nodejs -y
Verifikasi instalasi:
node -v
npm -v
Kamu seharusnya melihat output seperti v22.x.x untuk Node.js dan 11.x.x untuk npm.
Ghost-CLI adalah tool resmi dari tim Ghost untuk instalasi, manajemen, dan pembaruan Ghost. Install secara global dengan npm:
sudo npm install ghost-cli@latest -g
Verifikasi instalasi:
ghost --version
Ghost harus diinstal di direktori tersendiri. Buat direktori di /var/www/, lalu atur kepemilikannya ke user yang sedang aktif:
sudo mkdir -p /var/www/ghost
sudo chown $USER:$USER /var/www/ghost
sudo chmod 775 /var/www/ghost
Pindah ke direktori tersebut:
cd /var/www/ghost
Ini bagian utamanya. Dari dalam direktori /var/www/ghost, jalankan:
ghost install
Ghost-CLI akan memandu kamu melalui serangkaian pertanyaan konfigurasi secara interaktif. Berikut panduan pengisiannya:
| Pertanyaan dari Ghost-CLI | Isian yang Tepat |
|---|---|
| Blog URL | http://namadomain.com (gunakan http, bukan https) |
| MySQL hostname | 127.0.0.1 |
| MySQL username | ghost_user (sesuai Langkah 3) |
| MySQL password | Password yang sudah dibuat di Langkah 3 |
| Ghost database name | ghost_db (sesuai Langkah 3) |
| Set up Nginx? | Y |
| Set up SSL? | N (kita setup terpisah di Langkah 8) |
| Set up systemd? | Y |
| Start Ghost now? | Y |
https://namadomain.com di sini sementara SSL belum dikonfigurasi, Ghost akan langsung mengatur redirect HTTP → HTTPS. Karena sertifikat SSL belum ada, semua akses ke situsmu akan berakhir timeout. Gunakan http:// terlebih dahulu. Ghost-CLI akan otomatis memperbarui URL ini ke https:// sekaligus me-restart Ghost setelah SSL berhasil dikonfigurasi di Langkah 8.
localhost menginstruksikan MySQL untuk terhubung lewat Unix socket, sementara 127.0.0.1 menggunakan koneksi TCP/IP. Ghost (via driver mysql2) bekerja dengan TCP/IP, dan itulah yang tercatat di config.production.json setelah instalasi. Ikuti saja default Ghost-CLI dan isi 127.0.0.1.
Setelah instalasi selesai, verifikasi port yang digunakan Ghost:
ghost status
Perhatikan kolom Port pada output. Nilainya biasanya 2368 (default). Jika berbeda — misalnya 2369 — catat angka tersebut karena akan dibutuhkan di Langkah 8.
Setelah Ghost berhasil berjalan, saatnya mengaktifkan HTTPS. Pastikan dulu domain kamu sudah benar-benar mengarah ke IP server dan bisa diakses dari internet. Cek propagasi DNS-mu di dnschecker.org sebelum melanjutkan.
Masuk ke direktori Ghost, lalu jalankan perintah setup SSL:
cd /var/www/ghost
ghost setup ssl
Ghost-CLI akan meminta satu input: alamat email untuk notifikasi sertifikat dari Let's Encrypt. Gunakan email yang aktif dan bisa kamu akses — Let's Encrypt tidak memverifikasi apakah email valid, tapi akan mengirimkan peringatan penting ke sana saat sertifikat mendekati tanggal kedaluwarsa. Jika email palsu dipakai, peringatan tersebut tidak akan pernah sampai dan sertifikat bisa kedaluwarsa tanpa kamu sadari.
Setelah muncul ✔ Setting up SSL, lanjutkan dengan dua perintah berikut. ghost setup ssl tidak memperbarui URL Ghost secara otomatis dari http:// ke https://, sehingga harus dilakukan manual:
ghost config --url https://namadomain.com
ghost restart
Setelah Ghost restart, situsmu sudah berjalan penuh di HTTPS.
Unable to validate JWS :: Account not found, artinya acme.sh menyimpan sisa data akun dari percobaan sebelumnya yang tidak valid. Hapus data tersebut, lalu jalankan ulang:
sudo rm -rf /etc/letsencryptghost setup ssl
Setelah instalasi selesai, cek status Ghost:
ghost status
Jika semuanya berjalan lancar, kamu akan melihat status running di output.
Buka browser dan akses https://namadomain.com/ghost. Halaman setup awal Ghost akan menyambutmu dengan form berikut:
| Field | Keterangan |
|---|---|
| Site title | Nama situs atau blogmu. Muncul di tab browser, header tema, dan RSS feed. Bisa diubah kapan saja dari Settings. |
| Full name | Nama tampil akun administrator — yang muncul sebagai nama penulis di setiap artikel. Bisa nama asli, nama pena, atau nama brand. |
| Email address | Email untuk login ke panel admin Ghost. Harus email yang aktif dan bisa kamu akses, karena dipakai untuk reset password dan notifikasi sistem. Ini berbeda dari email SSL yang diisi saat setup Let's Encrypt. |
| Password | Minimal 10 karakter. Ghost menolak password yang terlalu umum, jadi gunakan kombinasi huruf, angka, dan karakter khusus. |
Setelah semua diisi, klik Create account & start publishing. Ghost akan membuat akun administrator dan langsung mengarahkan kamu ke dasbor.
Cek log Ghost untuk mengetahui akar masalahnya:
ghost log
Penyebab paling umum adalah konfigurasi database yang tidak cocok (username, password, atau nama database salah) atau versi Node.js yang tidak kompatibel. Pastikan kamu menggunakan Node.js 22 LTS, karena versi lebih lama tidak lagi didukung oleh Ghost.
accountDoesNotExistIni terjadi ketika acme.sh menyimpan sisa data akun dari percobaan sebelumnya yang tidak cocok dengan server Let's Encrypt. Solusinya: hapus seluruh direktori letsencrypt, verifikasi bahwa direktorinya benar-benar hilang, lalu jalankan ulang.
sudo rm -rf /etc/letsencrypt
ls /etc/letsencrypt
Output ls harus menunjukkan No such file or directory. Jika direktori masih ada (atau masih ada isinya), ulangi perintah rm sampai benar-benar bersih. Jika acme.sh masih terbaca sebagai upgrade (bukan install fresh) pada percobaan berikutnya, itu tanda bahwa penghapusan belum tuntas.
ghost setup ssl
No such challenge (404)Error ini berarti Let's Encrypt berhasil menjangkau server, tapi tidak menemukan konten yang diharapkan di URL verifikasi:
http://namadomain.com/.well-known/acme-challenge/<token>
Langkah pertama: cek apakah Nginx melayani webroot dengan benar
Buat direktori dan file tes secara manual, lalu cek apakah bisa diakses via HTTP:
sudo mkdir -p /var/www/ghost/system/nginx-root/.well-known/acme-challenge/
echo "tes-webroot" | sudo tee /var/www/ghost/system/nginx-root/.well-known/acme-challenge/testfile
curl http://namadomain.com/.well-known/acme-challenge/testfile
sudo rm -rf /var/www/ghost/system/nginx-root/.well-known
Dua kemungkinan hasil:
curl mengembalikan tes-webroot → Nginx benar melayani webroot. Lanjut ke diagnosis berikutnya.
curl mengembalikan halaman HTML Ghost → Nginx mem-proxy request /.well-known/ ke Ghost Express, bukan melayaninya sebagai file statis. Periksa konfigurasi Nginx dan pastikan ada blok berikut di dalam server {}, sebelum location /:
location /.well-known/acme-challenge/ {
root /var/www/ghost/system/nginx-root;
allow all;
}
Lalu: sudo nginx -t && sudo nginx -s reload
curl mengembalikan 404 dari Nginx sendiri (terlihat dari <center>nginx/x.x.x</center> tanpa X-Powered-By: Express) → ini justru konfirmasi bahwa Nginx sudah benar melayani webroot sebagai file statis. Masalah bukan di konfigurasi Nginx.
Langkah kedua: hapus data domain stale dari acme.sh
Jika Nginx sudah terbukti benar tapi ghost setup ssl tetap gagal dengan "No such challenge", penyebabnya adalah acme.sh menyimpan sisa data domain dari percobaan sebelumnya di /etc/letsencrypt/namadomain.com/, termasuk URL challenge yang sudah dibuang oleh Let's Encrypt. Hapus data domain tersebut secara spesifik, lalu coba ulang:
sudo rm -rf /etc/letsencrypt/namadomain.com/
ghost setup ssl
Jika masih gagal, baru hapus seluruh direktori letsencrypt:
sudo rm -rf /etc/letsencrypt
ghost setup ssl
Langkah ketiga: gunakan Certbot sebagai alternatif
Jika ghost setup ssl terus gagal, gunakan Certbot yang lebih andal sebagai pengganti acme.sh bawaan Ghost-CLI:
# Install Certbot dengan plugin Nginx
sudo apt install certbot python3-certbot-nginx -y
# Dapatkan sertifikat — Certbot menangani konfigurasi Nginx secara otomatis
sudo certbot --nginx -d namadomain.com --email admin@namadomain.com --agree-tos --non-interactive
# Perbarui URL Ghost ke HTTPS dan restart
ghost config --url https://namadomain.com
ghost restart
Certbot akan memperbarui konfigurasi Nginx untuk mengaktifkan HTTPS dan mengatur pembaruan sertifikat otomatis. Setelah perintah terakhir, Ghost sudah berjalan di HTTPS.
Jika ada web server lain yang aktif di port 80 (misalnya Apache), hentikan dulu sebelum instalasi:
sudo systemctl stop apache2
sudo systemctl disable apache2
502 Bad Gateway dari Nginx berarti Ghost tidak merespons di port yang dikonfigurasi Nginx. Cek dulu port yang sebenarnya digunakan Ghost:
ghost status
Perhatikan kolom Port pada output. Jika nilainya bukan 2368 (misalnya 2369), Nginx perlu disesuaikan agar mengarah ke port yang benar. Jalankan perintah berikut — ganti 2369 dengan port aktual dari output ghost status:
sudo sed -i 's/:2368/:2369/g' /etc/nginx/sites-available/namadomain.com.conf
sudo sed -i 's/:2368/:2369/g' /etc/nginx/sites-available/namadomain.com-ssl.conf
sudo nginx -t && sudo nginx -s reload
Jika instalasi bermasalah dan kamu ingin memulai dari nol, ikuti urutan ini secara lengkap. Jangan lewatkan satu pun langkahnya agar tidak ada sisa konfigurasi yang mengganggu instalasi berikutnya.
1. Hapus instalasi Ghost
Jalankan dari dalam direktori Ghost:
cd /var/www/ghost
ghost stop
ghost uninstall
ghost uninstall akan menghapus file Ghost, konfigurasi Nginx, dan service systemd secara otomatis. Setelahnya, hapus direktori instalasi Ghost yang tersisa:
sudo rm -rf /var/www/ghost
Jika ghost uninstall gagal atau direktori sudah tidak bisa diakses, hapus konfigurasi Nginx secara manual (ganti nama file sesuai domain kamu):
sudo rm -f /etc/nginx/sites-enabled/namadomain.com.conf
sudo rm -f /etc/nginx/sites-available/namadomain.com.conf
sudo nginx -s reload
2. Hapus database Ghost di MySQL
Database tidak dihapus oleh ghost uninstall, jadi harus dilakukan manual:
sudo mysql -u root
DROP DATABASE ghost_db;
DROP USER 'ghost_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
3. Hapus sisa data acme.sh
Jika SSL pernah dicoba sebelumnya, data akun acme.sh yang tersisa bisa menyebabkan error accountDoesNotExist di percobaan berikutnya:
sudo rm -rf /etc/letsencrypt
4. Buat ulang direktori instalasi
sudo mkdir -p /var/www/ghost
sudo chown $USER:$USER /var/www/ghost
sudo chmod 775 /var/www/ghost
Setelah keempat langkah ini selesai, tunggu sekitar 60 detik sebelum melanjutkan — ini memberi waktu kernel untuk melepas koneksi TCP lama di port 2368 dari instalasi sebelumnya. Kalau ghost install dijalankan terlalu cepat, Ghost-CLI bisa mendeteksi port 2368 masih sibuk dan memilih port lain (2369 dst.), yang akan menyebabkan mismatch dengan konfigurasi Nginx.
Opsional, verifikasi dulu bahwa port 2368 sudah benar-benar bebas sebelum melanjutkan:
sudo ss -tlnp | grep 2368
Jika tidak ada output, port sudah bebas. Baru lanjutkan kembali ke Langkah 3, jalankan ulang perintah SQL untuk membuat database dan user Ghost (bagian CREATE DATABASE hingga EXIT), lalu lanjutkan ke Langkah 7 untuk menginstal Ghost dari awal.
ghost start untuk menjalankan, ghost stop untuk menghentikan, ghost restart untuk memulai ulang, dan ghost update untuk memperbarui Ghost ke versi terbaru.
Sampai di sini dulu, Kawan Belajar! Ghost kini sudah terpasang di server Ubuntu-mu dengan Nginx sebagai reverse proxy dan SSL dari Let's Encrypt yang aktif. Selanjutnya, kamu bisa mulai menulis konten, mengatur tema, mengaktifkan fitur membership, atau menghubungkan domain kustom langsung dari panel admin Ghost. Jika ada kendala di tengah proses instalasi, tim support CloudKilat siap membantu kamu.
Jangan ragu untuk menghubungi tim support kami jika Anda memiliki pertanyaan atau masalah terkait layanan CloudKilat.