Cara Install Ghost CMS di Ubuntu
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.
Apa Itu Ghost?
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.
Prasyarat
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) |
Ghost-CLI mensyaratkan kamu login sebagai user non-root dengan hak
sudo. Jika kamu masih login sebagai root, ikuti Langkah 1 untuk membuat user baru sebelum melanjutkan.
Langkah 1: Siapkan User dan Update Sistem
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
Langkah 2: Install Nginx
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
Klik untuk melihat contoh output
● 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:
CloudKilat mengonfigurasi UFW dengan kebijakan default-deny (DROP) di setiap VPS baru, artinya semua port otomatis tertutup kecuali port 22 (SSH). Tiga perintah di bawah ini wajib dijalankan agar Nginx bisa menerima traffic di port 80 (HTTP) dan 443 (HTTPS). Melewatkan langkah ini akan membuat situsmu tidak bisa diakses sama sekali.
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.
Langkah 3: Install MySQL 8.0
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;
Simpan nama database, username, dan password yang baru dibuat. Ketiga informasi ini akan dibutuhkan saat Ghost-CLI menanyakannya di Langkah 7 nanti.
Langkah 4: Install Node.js 22 LTS
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.
Repositori bawaan Ubuntu sering menyediakan versi Node.js yang sudah usang dan tidak kompatibel dengan Ghost. Pastikan kamu menginstalnya melalui NodeSource seperti di atas.
Langkah 5: Install Ghost-CLI
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
Langkah 6: Siapkan Direktori Instalasi
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
Langkah 7: Install 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 |
Jika kamu memasukkan
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.
Keduanya merujuk ke mesin yang sama, tapi cara koneksinya berbeda.
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.
Saat kamu menjawab "Yes" pada opsi Nginx dan systemd: Ghost-CLI akan membuat konfigurasi Nginx lengkap serta mendaftarkan Ghost sebagai layanan systemd agar otomatis aktif saat server restart.
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.
Ghost-CLI otomatis memilih port berikutnya jika 2368 terdeteksi masih terpakai. Ini bisa terjadi saat melakukan instalasi ulang — proses Ghost lama meninggalkan koneksi TCP dalam status TIME_WAIT selama beberapa puluh detik, sehingga kernel masih menganggap port 2368 sibuk. Jika Ghost berjalan di port selain 2368, konfigurasi Nginx yang dibuat Ghost-CLI akan mismatch dan menyebabkan 502 Bad Gateway. Panduan perbaikannya ada di bagian Troubleshooting.
Proses validasi SSL bergantung pada propagasi DNS yang sudah selesai penuh dan konektivitas ke server Let's Encrypt. Dengan memisahkan langkah ini, Ghost tetap bisa berjalan lebih dulu, dan jika ada masalah saat setup SSL, kamu bisa mendiagnosis dan mengulangnya tanpa harus mengulang seluruh instalasi Ghost dari awal.
Langkah 8: Setup SSL
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.
Jika muncul error
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
Langkah 9: Verifikasi Instalasi
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.
Troubleshooting
Ghost Tidak Bisa Start
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.
SSL Gagal: Error accountDoesNotExist
Ini 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
SSL Gagal: Error 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.
Nginx Sudah Aktif di Port 80
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 Setelah Instalasi
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
Cara Membuat Ulang Instalasi Ghost dari Awal
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.
Beberapa perintah yang sering berguna setelah instalasi:
ghost start untuk menjalankan, ghost stop untuk menghentikan, ghost restart untuk memulai ulang, dan ghost update untuk memperbarui Ghost ke versi terbaru.
Kesimpulan
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.