Cara Install Discourse di VPS dengan Docker
Panduan resmi memasang Discourse di VPS dengan Docker: siapkan RAM dan swap, domain asli, SMTP, edit app.yml, jalankan rebuild, lalu atur TLS dan reverse proxy.
Install Discourse pada VPS: satu container, satu file konfigurasi
Untuk menginstal Discourse pada VPS, jalankan installer bawaan proyek, jawab beberapa pertanyaan pada wizard singkat, lalu tunggu proses build selesai. Discourse dirilis sebagai satu container Docker yang berisi aplikasi Rails, PostgreSQL, Redis, dan nginx. Semua perubahan yang nantinya Anda lakukan berada dalam satu file, /var/discourse/containers/app.yml, dan setiap perubahan diterapkan ke situs melalui proses rebuild.
Instalasi resmi terdiri atas discourse_docker: sebuah skrip shell launcher serta sekumpulan template YAML. Discourse tidak mendukung file Compose yang Anda tulis sendiri, dan container ini tidak dirancang untuk dipisah secara manual. Jika Anda terbiasa menjalankan service pada VPS dengan Docker Compose, bentuk pengelolaannya akan berbeda. Tidak ada docker compose up -d di sini, dan ./launcher rebuild app adalah proses deployment.
Hal yang dibutuhkan Discourse sebelum memulai
Empat persyaratan sering terlewat, dan masing-masing dapat menimbulkan masalah sebelum Anda mencapai halaman login.
- Memori. Satu container menjalankan PostgreSQL, Redis, Sidekiq, dan server web Ruby. Langkah build mengompilasi aset dan membutuhkan lebih banyak memori daripada situs yang sedang berjalan.
- Nama domain yang valid. Konfigurasi contoh yang disertakan menyatakannya dengan jelas: "Discourse tidak akan berfungsi dengan nomor IP saja."
- Jalur email keluar. Aktivasi akun, reset password, undangan admin, dan email ringkasan dikirim melalui SMTP (simple mail transfer protocol).
- Port 80 dan 443 harus tersedia pada host, kecuali Anda sengaja menempatkan Discourse di belakang proxy yang sudah berjalan.
The data behind this chart
[
{
"label": "Documented minimum",
"ram_gb": 1,
"storage_gb": 10
},
{
"label": "Documented recommended",
"ram_gb": 2,
"storage_gb": 20
}
]Dokumen instalasi resmi menetapkan batas minimum 1 GB RAM dengan swap dan 10 GB disk, serta merekomendasikan 2 GB RAM dengan 20 GB disk. Anggap baris pertama sebagai jumlah resource yang memungkinkan installer selesai, bukan jumlah yang Anda inginkan untuk menjalankan komunitas. Perbedaan ini penting karena penggunaan memori tertinggi terjadi saat build, bukan saat menangani trafik.
Arahkan domain ke server sebelum melakukan instalasi
Buat A record untuk hostname yang akan digunakan, lalu konfirmasikan dari server itu sendiri.
dig +short forum.example.com
curl -4 -s https://ifconfig.coKedua perintah harus menampilkan alamat yang sama. Keduanya harus cocok karena wizard penyiapan menjalankan pengujian koneksi terhadap hostname Anda, dan record yang masih mengarah ke tempat lain akan gagal dalam pengujian tersebut. Record yang dibuat dua menit lalu mungkin juga masih tersimpan dalam cache, jadi tunggu hingga TTL (time to live) lama berakhir, bukan mencoba mengatasi masalah dengan wizard.
Tentukan sekarang apakah record akan diproxy oleh CDN. Record yang diproxy menyembunyikan alamat server Anda, lalu permintaan sertifikat container gagal karena challenge ACME (automatic certificate management environment) dijawab oleh proxy, bukan oleh Discourse. Biarkan record tidak diproxy untuk instalasi pertama.
Jalankan installer resmi
Satu perintah menginstal git, menginstal Docker menggunakan skrip instalasi milik Docker, meng-clone discourse_docker ke /var/discourse, lalu memulai wizard penyiapan.
wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/main/install-discourse | sudo bashJika Docker sudah tersedia di server dan Anda ingin melihat setiap langkahnya, lakukan pekerjaan yang sama secara manual.
sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
./discourse-setupJalankan sebagai root. Jika dijalankan sebagai pengguna biasa, discourse-setup langsung berhenti dengan This script must be run as root. Please sudo or log in as root first.. Jika Docker tidak tersedia di server, proses berhenti dengan Docker is not installed. Please install Docker first. karena clone manual tidak menginstal apa pun untuk Anda.
Hal yang ditanyakan wizard penyiapan dan yang ditulisnya
Per Agustus 2026, discourse-setup adalah wrapper tipis. Wrapper ini menjalankan discourse/setup-wizard:release sebagai container dengan jaringan host dan Docker socket yang di-mount agar wizard dapat memeriksa mesin yang sedang dikonfigurasinya. Wizard menanyakan hostname dan alamat email admin, lalu blok SMTP Anda. Wizard menulis containers/app.yml, kemudian menjalankan build ulang.
Ada dua perilaku yang perlu diketahui sebelum memulai. Jika mesin kekurangan memori dan tidak memiliki swap, wizard berhenti dan menawarkan untuk membuatnya: wrapper kemudian membuat /swapfile berukuran 2 GB, menambahkannya ke /etc/fstab, mengatur vm.swappiness = 10 di /etc/sysctl.d/30-discourse-swap.conf, lalu menjalankan wizard kembali. Setelah wizard selesai, wizard mencetak Rebuilding app in 5 seconds (Ctrl+C to cancel)... dan menjalankan ./launcher rebuild app pada host. Proses build ini memerlukan beberapa menit pada VPS kecil, dan build pertama memerlukan waktu paling lama karena setiap aset dikompilasi dari awal.
./discourse-setup --help mencantumkan flag yang penting saat terjadi masalah. --skip-rebuild menulis konfigurasi tanpa menjalankan build, sedangkan --skip-connection-test melewati pemeriksaan DNS dan port. Gunakan --skip-connection-test hanya jika Anda sudah mengetahui penyebab kegagalan pengujian, misalnya ketika host berada di belakang firewall jaringan yang Anda kelola.
Baca app.yml sebelum rebuild pertama
Wizard menulis file yang sekarang harus Anda pelihara. Buka file tersebut dengan sudo nano /var/discourse/containers/app.yml. Bagian-bagian berikut menentukan hampir seluruh konfigurasi.
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
expose:
- "80:80" # http
- "443:443" # https
env:
DISCOURSE_HOSTNAME: "forum.example.com"
DISCOURSE_DEVELOPER_EMAILS: "you@example.com"
DISCOURSE_SMTP_ADDRESS: smtp.example.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: user@example.com
DISCOURSE_SMTP_PASSWORD: "your-smtp-password"DISCOURSE_HOSTNAME adalah alamat yang digunakan situs untuk merespons, dan Discourse membuat tautan berdasarkan alamat tersebut. Nilai yang salah dapat membuat situs berhasil dimuat sekali, lalu mengarahkan Anda ke tempat lain. DISCOURSE_DEVELOPER_EMAILS adalah daftar yang dipisahkan koma. Alamat-alamat tersebut otomatis menjadi administrator saat pendaftaran pertama. Masukkan alamat Anda sendiri di sana dan lakukan pendaftaran menggunakan alamat tersebut, karena itulah cara akun administrator pertama dibuat.
File ini menyimpan password SMTP dalam teks biasa. Batasi akses ke direktori tersebut dengan sudo chmod 700 /var/discourse/containers. File ini juga menggunakan YAML, sehingga spasi menjadi bagian dari konfigurasi. Key yang tidak sejajar akan membuat build gagal dengan parse error dan situs tidak dapat digunakan. Salah satu masalah umum didokumentasikan di dalam sample file itu sendiri. # di dalam password yang tidak diapit tanda kutip akan memulai komentar. Karena itu, apit dengan tanda kutip setiap password yang mengandung karakter tersebut.
Email adalah tahap yang paling sering menghentikan instalasi
Per Agustus 2026, wizard memungkinkan Anda melewati konfigurasi SMTP dan menggunakan login Discourse ID. app.yml juga memiliki switch DISCOURSE_SKIP_EMAIL_SETUP yang sesuai, yang dijelaskan di sana sebagai opsi untuk melewati validasi konfigurasi email. Melewati tahap ini wajar jika Anda baru ingin mencoba software tersebut. Namun, pilihan ini tidak sesuai untuk komunitas karena tanpa email keluar, pengguna tidak dapat mengaktifkan akun atau mereset password.
Masalah praktisnya adalah sebagian besar provider VPS memblokir port keluar 25, sehingga mail server biasa pada server tersebut tidak dapat mengirimkan email. Gunakan relay terautentikasi pada port 587, atau port 465 dengan TLS implisit (transport layer security). Untuk port 465, tetapkan DISCOURSE_SMTP_FORCE_TLS: true, sesuai rekomendasi sample config untuk port tersebut. Uji keterjangkauan dari host sebelum Anda melakukan rebuild.
nc -vz smtp.example.com 587Hasil yang benar adalah satu baris yang diakhiri dengan succeeded!. Jika sebuah command berhenti tanpa respons lalu mengalami timeout, berarti port tersebut diblokir pada jalur keluar dari VPS Anda. Tidak ada pengaturan Discourse yang dapat memperbaikinya. Gunakan port yang diizinkan oleh provider, atau minta provider membuka port tersebut.
Setelah situs aktif, kirim pesan pengujian dari halaman Email di Admin, lalu baca tab Skipped dan Bounced pada halaman yang sama. Pada tab tersebut, Discourse mencatat email yang ditolak untuk dikirim dan email yang ditolak oleh relay. Tab tersebut juga mencantumkan alasannya, sehingga lebih cepat daripada membaca log.
TLS: biarkan container memperoleh sertifikatnya sendiri
Jika Discourse menggunakan port 80 dan 443, gunakan penerbitan sertifikat bawaan Discourse. Hapus tanda komentar pada dua baris template SSL yang ditunjukkan di atas, lalu lakukan rebuild. Template tersebut mengatur acme.sh, menyimpan sertifikat dalam volume bersama di /shared/ssl, memperbaruinya secara berkala di dalam container, dan mengatur Discourse untuk selalu menggunakan HTTPS.
Port 80 harus tetap dapat diakses dari Internet agar proses ini berhasil karena challenge HTTP dijawab melalui port tersebut. Firewall yang hanya mengizinkan port 443 akan menghasilkan build yang selesai, tetapi sertifikat tidak pernah diterbitkan. Periksa hasilnya dengan ./launcher logs app segera setelah rebuild.
Perlukah menempatkan nginx atau Caddy di depan?
Jika Discourse adalah satu-satunya web service pada VPS, jangan lakukan itu. Container sudah menjalankan nginx yang telah dioptimalkan. Proxy kedua menambah satu hop, sertifikat lain yang harus diperbarui, serta sumber baru masalah header.
Gunakan proxy di depannya jika VPS yang sama juga melayani situs lain. Tambahkan templates/web.socketed.template.yml ke daftar template, nonaktifkan komentar pada kedua baris expose, dan biarkan kedua template SSL tetap dikomentari. Container kemudian mendengarkan pada unix socket di /var/discourse/shared/standalone/nginx.http.sock dan sama sekali tidak membuka port. Dengan demikian, port 80 dan 443 tersedia untuk proxy Anda sendiri.
server {
listen 443 ssl;
server_name forum.example.com;
location / {
proxy_pass http://unix:/var/discourse/shared/standalone/nginx.http.sock:;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
}
}Tanda titik dua setelah .sock merupakan bagian dari sintaks unix socket nginx. sudo nginx -t menolak konfigurasi tanpa tanda tersebut. X-Forwarded-Proto juga wajib ada. Discourse menulis tautan absolut. Tanpa header itu, Discourse menghasilkan tautan http:// pada halaman HTTPS, dan browser memblokirnya sebagai mixed content. Setelah container menggunakan socket, TLS menjadi tanggung jawab Anda. Terbitkan sertifikat pada host dengan Certbot pada Ubuntu 24.04 dan nginx. Jika Anda belum menentukan proxy yang akan digunakan, perbandingan nginx, Caddy, dan Traefik menjelaskan kompromi dari setiap pilihan.
Rebuild, upgrade, dan perintah yang akan Anda gunakan
cd /var/discourse
./launcher rebuild apprebuild menghancurkan container yang sedang berjalan, membuat container baru dari app.yml, lalu menjalankannya. Situs tidak dapat diakses selama seluruh proses build, jadi perlakukan setiap perubahan konfigurasi sebagai downtime terjadwal selama beberapa menit.
Perubahan yang hanya dilakukan pada nilai di bawah env: tidak memerlukan proses tersebut. ./launcher destroy app && ./launcher start app membuat ulang container dari image yang sudah Anda build, dan proses ini hanya memerlukan beberapa detik. Perubahan apa pun di bawah templates: atau hooks: mengubah image itu sendiri, sehingga memerlukan rebuild penuh.
Upgrade tersedia melalui dua cara. Point release dapat diterapkan dari antarmuka web di /admin/upgrade, yang disediakan oleh plugin docker_manager yang di-clone oleh app.yml selama proses build. Perubahan pada base image atau template berasal dari git.
cd /var/discourse
git pull
./launcher rebuild appRebuild sering menyebabkan server kecil gagal karena kompilasi aset menggunakan memori paling besar dalam seluruh sistem. Jika build berhenti di tengah proses dan dmesg menampilkan baris seperti Out of memory: Killed process yang menyebut proses ruby, berarti memori habis selama build, meskipun situs sebelumnya berjalan normal. Tambahkan swap, lalu jalankan rebuild lagi.
./launcher logs app
./launcher enter app
./launcher cleanuplogs menampilkan output container, enter membuka shell di dalamnya, dan cleanup menghapus container yang telah dihentikan selama lebih dari 24 jam. Jalankan cleanup secara berkala, karena setiap rebuild menyisakan container lama dan ruang disk pada VPS kecil dapat habis tanpa terlihat.
Cadangan dan file yang tidak termasuk dalam cadangan
Buat cadangan dari halaman Backups di Admin. Arsip disimpan pada host di /var/discourse/shared/standalone/backups/default/. Pekerjaan yang sama dapat dijalankan dari shell.
cd /var/discourse
./launcher enter app
discourse backupdiscourse restore <filename> membalikkan proses tersebut, dan pemulihan ditolak sampai Anda menjalankan discourse enable_restore. Pengaman ini mencegah perintah yang tidak disengaja menimpa forum yang sedang aktif.
Ada dua hal yang harus Anda tangani sendiri. Arsip berisi database dan hanya berisi file yang diunggah jika pengaturan cadangan yang menyertakan upload diaktifkan. Karena itu, periksa pengaturan tersebut sebelum mengandalkan cadangan. Arsip tidak pernah berisi app.yml. Jadi, pemulihan ke VPS baru tetap memerlukan hostname dan blok SMTP Anda. File tersebut juga harus disalin keluar dari server.
Arsip juga disimpan pada disk yang sama dengan situs yang dilindunginya. Itu bukan cadangan yang memadai. Salin arsip ke lokasi lain secara terjadwal.
rsync -avz root@forum.example.com:/var/discourse/shared/standalone/backups/default/ ~/discourse-backups/Biaya forum yang ramai dalam RAM
Bootstrap menetapkan UNICORN_WORKERS dan db_shared_buffers berdasarkan memori dan CPU yang terdeteksi, sedangkan konfigurasi contoh membatasi buffer bersama hingga seperempat dari total memori. Setiap worker unicorn adalah proses Ruby penuh, dan Sidekiq menjalankan job latar belakang di sampingnya. Karena itu, penggunaan memori lebih dipengaruhi oleh jumlah request bersamaan daripada jumlah anggota terdaftar. Forum yang sepi dengan beberapa ratus anggota bukan workload berat. Hal lain yang menggunakan server tersebut biasanya lebih menentukan. Jika hal itu adalah pustaka foto, batas minimum RAM yang diukur dalam perbandingan PhotoPrism dan Immich akan menunjukkan apakah masih tersedia cukup kapasitas untuk menyelesaikan rebuild Discourse.
Jangan menentukan ukuran server berdasarkan angka dalam sebuah artikel, termasuk artikel ini. Ukur lingkungan Anda sendiri.
free -m
docker stats --no-streamPenggunaan swap yang terus-menerus disertai halaman yang lambat berarti RAM Anda tidak mencukupi. Jika penggunaan memori stabil tetapi halaman tetap lambat, penyebabnya biasanya berbeda. Baca ./launcher logs app sebelum membeli plan yang lebih besar. Tambahkan pemeriksaan dari luar server juga, karena forum yang kehabisan memori pada pukul 3 pagi dapat gagal tanpa terlihat. Monitor status Uptime Kuma yang di-host sendiri pada host terpisah akan memberi tahu Anda sebelum anggota forum menyadarinya.
Saat Discourse bukan pilihan yang tepat
Discourse adalah aplikasi besar dengan instalasi yang berat dan siklus rebuild untuk setiap pengaturan yang berada di app.yml. Biaya tersebut memberikan perangkat moderasi yang lengkap dan fitur pencarian yang tetap berfungsi meskipun arsip sudah besar. Untuk tiga puluh orang yang hanya membutuhkan tempat untuk berdiskusi, aplikasi ini lebih besar daripada kebutuhan percakapan tersebut. Baca perbandingan software forum yang di-host sendiri terlebih dahulu, lalu pilih Discourse karena Anda membutuhkan fitur yang disediakannya, bukan hanya karena namanya sudah Anda kenal.
FAQ
Dapatkah saya menginstal Discourse pada VPS tanpa nama domain?
Tidak. Konfigurasi bawaan menyatakan bahwa Discourse tidak akan berfungsi dengan nomor IP langsung, dan DISCOURSE_HOSTNAME diperlukan. Discourse membuat tautan absolut berdasarkan hostname tersebut, sehingga alamat IP akan menyebabkan tautan rusak dan penerbitan sertifikat gagal. Buat A record sebelum memulai, lalu pastikan dengan dig +short forum.example.com bahwa record tersebut mengarah ke alamat server Anda.
Apakah saya harus mengonfigurasi SMTP untuk menyelesaikan instalasi?
Per Agustus 2026, Anda dapat melewati langkah tersebut. Wizard penyiapan menawarkan login Discourse ID sebagai gantinya, dan app.yml memiliki opsi untuk melewati validasi penyiapan email. Untuk penggunaan lebih dari sekadar uji coba awal, konfigurasikan SMTP karena aktivasi akun dan pengaturan ulang kata sandi sama-sama dikirim melalui email. Gunakan relay terautentikasi pada port 587 atau 465 karena sebagian besar penyedia VPS memblokir port keluar 25.
Mengapa rebuild Discourse saya gagal di tengah proses?
Memori biasanya menjadi penyebabnya. Kompilasi aset selama proses build membutuhkan lebih banyak memori daripada situs yang sedang berjalan, sehingga server yang dapat melayani forum dengan baik tetap dapat gagal melakukan rebuild. Jika dmesg menampilkan Out of memory: Killed process yang menyebut proses Ruby, tambahkan swap (swapfile bawaan wizard berukuran 2 GB), lalu jalankan ./launcher rebuild app lagi. Build yang berhenti karena error YAML biasanya menunjukkan kesalahan indentasi dalam app.yml.
Apakah Discourse sebaiknya berjalan di belakang nginx atau Caddy milik saya?
Hanya jika VPS juga melayani situs lain. Jika Discourse adalah satu-satunya layanan pada server, biarkan container menggunakan port 80 dan 443 serta menerbitkan sertifikatnya sendiri agar lebih sedikit komponen yang perlu dikelola. Untuk berbagi mesin dengan layanan lain, tambahkan templates/web.socketed.template.yml, beri komentar pada baris expose, lalu teruskan proxy ke unix socket di /var/discourse/shared/standalone/nginx.http.sock. Teruskan X-Forwarded-Proto, atau Discourse akan menghasilkan tautan http:// pada halaman HTTPS.
Bagaimana cara mencadangkan Discourse yang di-host sendiri?
Gunakan halaman Backups di Admin, atau jalankan discourse backup setelah ./launcher enter app. Arsip disimpan pada host di /var/discourse/shared/standalone/backups/default/. Pastikan pengaturan yang menyertakan upload telah diaktifkan, salin /var/discourse/containers/app.yml bersama arsip tersebut, lalu pindahkan keduanya ke mesin lain karena cadangan pada disk yang sama dengan situs tidak akan bertahan dari kegagalan yang menjadi alasan pembuatan cadangan tersebut.