SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-13

Cara Instal Discourse di VPS dengan Docker

Pelajari instalasi Discourse di VPS dengan Docker resmi, termasuk RAM dan swap, domain, SMTP, app.yml, perintah rebuild, TLS, dan reverse proxy.

Instal Discourse pada VPS: satu container, satu file konfigurasi

Untuk menginstal Discourse pada VPS, jalankan installer bawaan proyek, jawab beberapa pertanyaan dalam wizard singkat, lalu tunggu proses build selesai. Discourse dirilis sebagai satu container Docker yang berisi aplikasi Rails, PostgreSQL, Redis, dan nginx. Semua perubahan yang akan Anda lakukan selanjutnya tersimpan dalam satu file, /var/discourse/containers/app.yml, dan setiap perubahan diterapkan ke situs melalui proses rebuild.

Instalasi resmi menggunakan discourse_docker: skrip shell launcher dan sekumpulan template YAML. Discourse tidak mendukung file Compose yang Anda tulis sendiri, dan container ini tidak dirancang untuk dipisahkan secara manual. Jika Anda terbiasa menjalankan service pada VPS dengan Docker Compose, gunakan pendekatan yang berbeda. Di sini tidak ada docker compose up -d, dan ./launcher rebuild app adalah proses deploy.

Hal yang dibutuhkan Discourse sebelum Anda mulai

Empat persyaratan sering terlewat, dan masing-masing menimbulkan masalah sebelum Anda mencapai halaman login.

  • Memori. Satu container menjalankan PostgreSQL, Redis, Sidekiq, dan server web Ruby. Tahap build mengompilasi aset dan membutuhkan lebih banyak memori daripada situs yang sedang berjalan.
  • Nama domain yang valid. Contoh konfigurasi yang disertakan menyatakannya dengan jelas: "Discourse tidak akan berfungsi dengan nomor IP saja."
  • Jalur email keluar. Aktivasi akun, pengaturan ulang kata sandi, undangan admin, dan email digest semuanya dikirim melalui SMTP (simple mail transfer protocol).
  • Port 80 dan 443 yang tersedia pada host, kecuali Anda sengaja menempatkan Discourse di belakang proxy yang sudah Anda jalankan.
ChartDiscourse published hardware requirements (official install docs, August 2026)
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 yang memungkinkan installer selesai, bukan jumlah yang Anda inginkan untuk menjalankan komunitas. Perbedaan ini penting karena puncak penggunaan memori terjadi saat build, bukan akibat trafik.

Arahkan domain ke server sebelum menginstal

Buat A record untuk hostname yang akan Anda gunakan, lalu konfirmasikan dari server itu sendiri.

dig +short forum.example.com
curl -4 -s https://ifconfig.co

Kedua perintah harus menampilkan alamat yang sama. Keduanya harus cocok karena wizard penyiapan menjalankan pengujian koneksi ke hostname Anda. Record yang masih mengarah ke tempat lain akan gagal dalam pengujian tersebut. Record yang Anda buat dua menit lalu mungkin juga masih tersimpan dalam cache. Jadi, tunggu hingga TTL (time to live) lama berakhir, bukan mencoba mengatasi masalah melalui wizard.

Tentukan sekarang apakah record akan diproxy oleh CDN. Record yang diproxy menyembunyikan alamat server Anda. Akibatnya, 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 penginstal 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 bash

Jika Docker sudah tersedia di server dan Anda ingin melihat setiap langkahnya, lakukan proses yang sama secara manual.

sudo -s
git clone https://github.com/discourse/discourse_docker.git /var/discourse
cd /var/discourse
./discourse-setup

Jalankan 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 belum 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 tersebut menjalankan discourse/setup-wizard:release sebagai container dengan jaringan host dan socket Docker yang di-mount agar wizard dapat memeriksa mesin yang sedang dikonfigurasinya. Wizard menanyakan hostname dan alamat email admin, kemudian konfigurasi SMTP Anda. Wizard menulis containers/app.yml, lalu menjalankan build ulang.

Ada dua perilaku yang perlu diketahui sebelum memulai. Jika mesin kekurangan memori dan tidak memiliki swap, wizard akan berhenti dan menawarkan untuk membuatnya. Wrapper kemudian membuat /swapfile berukuran 2 GB, menambahkannya ke /etc/fstab, menetapkan vm.swappiness = 10 di /etc/sysctl.d/30-discourse-swap.conf, lalu menjalankan wizard lagi. Setelah wizard selesai, wizard menampilkan Rebuilding app in 5 seconds (Ctrl+C to cancel)... dan menjalankan ./launcher rebuild app pada host. Proses build tersebut memerlukan waktu beberapa menit pada VPS kecil. Build pertama memerlukan waktu paling lama karena setiap aset dikompilasi dari awal.

./discourse-setup --help mencantumkan flag yang penting ketika 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 build ulang pertama

Wizard menulis file yang sekarang harus Anda kelola. Buka file tersebut dengan sudo nano /var/discourse/containers/app.yml. 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 menerima permintaan, dan Discourse membuat tautannya berdasarkan alamat tersebut. Nilai yang salah dapat membuat situs hanya berhasil dimuat sekali, lalu mengarahkan Anda ke alamat lain. DISCOURSE_DEVELOPER_EMAILS adalah daftar yang dipisahkan koma. Alamat-alamat tersebut otomatis menjadi admin saat pendaftaran pertama. Masukkan alamat Anda sendiri di sana dan lakukan pendaftaran menggunakan alamat tersebut. Dengan cara ini, akun admin pertama dibuat.

File ini menyimpan kata sandi 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 menyebabkan build gagal dengan kesalahan parsing dan membuat situs tidak tersedia. Ada satu jebakan yang didokumentasikan di dalam file contoh. # di dalam kata sandi yang tidak diapit tanda kutip akan memulai komentar. Karena itu, apit dengan tanda kutip setiap kata sandi 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 untuk peninjauan awal terhadap software. Namun, pilihan ini tidak tepat untuk komunitas, karena tanpa email keluar, pengguna tidak dapat mengaktifkan akun atau mereset password.

Masalah praktisnya adalah sebagian besar penyedia VPS memblokir port keluar 25, sehingga mail server biasa pada server tersebut tidak dapat mengirim 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, seperti yang direkomendasikan oleh konfigurasi contoh untuk port tersebut. Uji keterjangkauan dari host sebelum melakukan build ulang.

nc -vz smtp.example.com 587

Hasil yang benar terdiri atas satu baris yang diakhiri succeeded!. Jika sebuah command berhenti merespons 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 penyedia, atau minta penyedia membukanya.

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 pemeriksaannya lebih cepat daripada membaca log.

TLS: biarkan container menerbitkan sertifikatnya sendiri

Jika Discourse menggunakan port 80 dan 443, gunakan mekanisme penerbitan bawaan Discourse. Hapus tanda komentar pada dua baris template SSL yang ditunjukkan di atas, lalu lakukan rebuild. Template tersebut mengatur acme.sh, menyimpan sertifikat di volume bersama pada /shared/ssl, memperbaruinya secara terjadwal di dalam container, dan mengatur Discourse agar selalu menggunakan HTTPS.

Port 80 harus tetap dapat diakses dari Internet agar proses ini berhasil, karena HTTP challenge dijawab melalui port tersebut. Firewall yang hanya mengizinkan port 443 akan menghasilkan build yang selesai, tetapi sertifikat tidak pernah diterbitkan. Periksa hasilnya langsung setelah rebuild dengan ./launcher logs app.

Tempatkan nginx atau Caddy di depan?

Jika Discourse adalah satu-satunya layanan web di VPS, jangan lakukan itu. Container sudah menjalankan nginx yang telah dioptimalkan. Proxy kedua menambah satu hop, sertifikat lain yang harus diperbarui, dan sumber baru masalah header.

Gunakan proxy di depannya jika VPS yang sama melayani situs lain. Tambahkan templates/web.socketed.template.yml ke daftar template, komentari kedua baris expose, dan biarkan kedua template SSL tetap dikomentari. Container kemudian hanya mendengarkan pada unix socket di /var/discourse/shared/standalone/nginx.http.sock dan tidak menggunakan port apa pun. 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;
  }
}

Titik dua setelah .sock merupakan bagian dari sintaks unix socket nginx. sudo nginx -t akan menolak konfigurasi tanpanya. X-Forwarded-Proto juga wajib ada. Discourse menulis tautan absolut. Tanpa header tersebut, 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 yang harus Anda pertimbangkan.

Rebuild, upgrade, dan perintah yang akan Anda gunakan

cd /var/discourse
./launcher rebuild app

rebuild menghancurkan container yang sedang berjalan, membuat container baru dari app.yml, lalu menjalankannya. Situs tidak dapat diakses selama seluruh proses build. Karena itu, perlakukan setiap perubahan konfigurasi sebagai downtime terjadwal selama beberapa menit.

Perubahan hanya pada nilai di bawah env: tidak memerlukan proses tersebut. ./launcher destroy app && ./launcher start app membuat ulang container dari image yang sudah Anda build. Proses ini hanya memerlukan beberapa detik. Perubahan apa pun di bawah templates: atau hooks: mengubah image itu sendiri. Karena itu, perubahan tersebut memerlukan rebuild penuh.

Upgrade dilakukan melalui 2 cara. Point release 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 app

Rebuild 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 kembali.

./launcher logs app
./launcher enter app
./launcher cleanup

logs menampilkan output container, enter membuka shell di dalamnya, dan cleanup menghapus container yang sudah berhenti selama lebih dari 24 jam. Jalankan cleanup secara berkala karena setiap rebuild meninggalkan container lama, dan disk pada VPS kecil dapat habis tanpa disadari.

Pencadangan, dan file yang tidak termasuk dalam cadangan

Buat cadangan dari halaman Backups di Admin. Arsip tersimpan pada host di /var/discourse/shared/standalone/backups/default/. Pekerjaan yang sama dapat dijalankan dari shell.

cd /var/discourse
./launcher enter app
discourse backup

discourse restore <filename> membatalkan proses tersebut dan pemulihan ditolak sampai Anda menjalankan discourse enable_restore. Perlindungan ini mencegah perintah yang salah menimpa forum yang sedang aktif.

Ada dua hal yang harus Anda tangani sendiri. Arsip berisi database dan hanya berisi file yang diunggah jika pengaturan pencadangan yang menyertakan upload diaktifkan. Jadi, periksa pengaturan tersebut sebelum mengandalkannya. Arsip tidak pernah berisi app.yml. Karena itu, pemulihan ke VPS baru tetap memerlukan hostname dan blok SMTP Anda. Salin file tersebut ke luar server.

Arsip juga berada 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. Konfigurasi contoh membatasi buffer bersama hingga seperempat dari total memori. Setiap worker unicorn merupakan proses Ruby penuh, sedangkan Sidekiq menjalankan pekerjaan latar belakang di sampingnya. Karena itu, penggunaan memori mengikuti jumlah permintaan bersamaan, bukan jumlah anggota yang terdaftar. Forum yang sepi dengan beberapa ratus anggota bukan beban kerja yang berat.

Jangan menentukan ukuran server berdasarkan angka dalam artikel, termasuk artikel ini. Ukur lingkungan Anda sendiri.

free -m
docker stats --no-stream

Penggunaan swap yang terus-menerus disertai halaman yang lambat berarti RAM Anda tidak mencukupi. Jika penggunaan memori stabil tetapi halaman tetap lambat, biasanya penyebabnya berbeda. Baca ./launcher logs app sebelum membeli paket yang lebih besar. Tambahkan pemeriksaan dari luar server juga, karena forum yang kehabisan memori pada pukul 3am dapat gagal tanpa terlihat. monitor status Uptime Kuma yang di-host sendiri pada host terpisah akan memberi tahu Anda sebelum anggota forum menyadarinya.

Kapan 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 ini memberikan fitur moderasi yang lengkap dan pencarian yang tetap berfungsi ketika 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 self-hosted terlebih dahulu, lalu pilih Discourse karena Anda membutuhkan fitur yang disediakannya, bukan 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 alamat IP saja, dan DISCOURSE_HOSTNAME diperlukan. Discourse membuat tautan absolut dari hostname tersebut, sehingga alamat IP akan merusak tautan dan menghambat penerbitan sertifikat. 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 switch untuk melewati validasi penyiapan email. Untuk penggunaan lebih dari sekadar uji coba awal, konfigurasikan SMTP karena aktivasi akun dan pengaturan ulang kata sandi 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?

Penyebab yang paling umum adalah memori. Kompilasi aset selama proses build memerlukan lebih banyak memori daripada situs yang sedang berjalan. Karena itu, server yang dapat melayani forum dengan baik tetap dapat gagal saat 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 ditempatkan di balik nginx atau Caddy milik saya?

Hanya jika VPS juga melayani situs lain. Jika Discourse menjadi satu-satunya aplikasi pada server, biarkan container menggunakan port 80 dan 443 serta menerbitkan sertifikatnya sendiri. Dengan begitu, lebih sedikit komponen yang perlu dikelola. Untuk berbagi mesin dengan situs lain, tambahkan templates/web.socketed.template.yml, beri komentar pada baris expose, lalu 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-hosting 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. Cadangan pada disk yang sama dengan situs tidak akan bertahan dari kegagalan yang ingin ditangani oleh cadangan tersebut.