SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-29

Cara Pasang Discourse di VPS Menggunakan Docker

Ketahui cara memasang Discourse di VPS dengan Docker rasmi. Panduan ini merangkumi penyediaan RAM, swap, SMTP, konfigurasi app.yml, serta proses rebuild untuk aplikasi anda.

Memasang Discourse pada VPS: satu kontena, satu fail konfigurasi

Untuk memasang Discourse pada VPS, anda perlu menjalankan pemasang rasmi projek tersebut, menjawab beberapa soalan dalam wizard, dan menunggu proses binaan selesai. Discourse diedarkan sebagai satu kontena Docker tunggal yang mengandungi aplikasi Rails, PostgreSQL, Redis, dan nginx. Segala perubahan yang akan anda lakukan kemudiannya terletak dalam satu fail, /var/discourse/containers/app.yml, dan setiap perubahan akan diaplikasikan pada laman web melalui proses binaan semula (rebuild).

Pemasangan rasmi adalah discourse_docker: satu skrip shell launcher berserta set templat YAML. Discourse tidak menyokong fail Compose yang ditulis sendiri, dan kontena tersebut tidak direka untuk dipecahkan secara manual. Jika anda biasa dengan menjalankan servis pada VPS menggunakan Docker Compose, jangkakan struktur yang berbeza. Tiada docker compose up -d di sini, dan ./launcher rebuild app merupakan cara untuk melakukan deploy.

Keperluan Discourse sebelum anda bermula

Empat keperluan sering memerangkap pengguna, dan setiap satunya akan menjadi masalah sebelum anda sampai ke halaman log masuk.

  • Memori. Satu kontena menjalankan PostgreSQL, Redis, Sidekiq dan pelayan web Ruby. Langkah binaan (build) menyusun aset dan memerlukan lebih banyak memori berbanding tapak yang sedang berjalan.
  • Nama domain sebenar. Konfigurasi contoh yang dibekalkan menyatakan dengan jelas: "Discourse tidak akan berfungsi dengan alamat IP sahaja."
  • Laluan mel keluar. Pengaktifan akaun, tetapan semula kata laluan, jemputan admin dan mel ringkasan semuanya dihantar melalui SMTP (simple mail transfer protocol).
  • Port 80 dan 443 mestilah bebas pada hos, melainkan anda sengaja meletakkan Discourse di belakang proksi yang sudah sedia ada.
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 pemasangan rasmi menetapkan had minimum sebanyak 1 GB RAM dengan swap dan 10 GB storan, serta mengesyorkan 2 GB RAM dengan 20 GB storan. Anggap baris pertama sebagai angka yang membolehkan pemasang selesai, bukan angka yang anda mahukan untuk menjalankan komuniti. Perbezaan ini penting kerana puncak penggunaan memori berlaku semasa proses binaan, bukan disebabkan trafik.

Halakan domain ke pelayan sebelum anda memasang

Cipta rekod A untuk nama hos yang akan anda gunakan, kemudian sahkan rekod tersebut daripada pelayan itu sendiri.

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

Kedua-dua arahan mesti memaparkan alamat yang sama. Ia perlu sepadan kerana wizard pemasangan menjalankan ujian sambungan terhadap nama hos anda, dan rekod yang masih menghala ke tempat lain akan menyebabkan ujian tersebut gagal. Rekod yang anda cipta dua minit yang lalu mungkin masih dalam cache, jadi tunggu sehingga TTL (time to live) yang lama tamat berbanding cuba melawan wizard tersebut.

Tentukan sekarang sama ada rekod tersebut akan diproksi oleh CDN. Rekod yang diproksi akan menyembunyikan alamat pelayan anda, dan permintaan sijil bekas (container) kemudiannya akan gagal kerana cabaran ACME (automatic certificate management environment) dijawab oleh proksi dan bukannya oleh Discourse. Pastikan rekod tidak diproksi untuk pemasangan kali pertama.

Jalankan pemasang rasmi

Satu arahan memasang git, memasang Docker menggunakan skrip pemasangan Docker sendiri, mengklon discourse_docker ke dalam /var/discourse, dan memulakan wizard persediaan.

wget -qO- https://raw.githubusercontent.com/discourse/discourse_docker/main/install-discourse | sudo bash

Jika Docker sudah ada pada pelayan dan anda lebih suka melihat setiap langkah, lakukan kerja tersebut secara manual.

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

Jalankannya sebagai root. Jika dimulakan sebagai pengguna biasa, discourse-setup akan berhenti serta-merta dengan This script must be run as root. Please sudo or log in as root first.. Tanpa Docker pada pelayan, ia akan berhenti dengan Docker is not installed. Please install Docker first., kerana klon manual tidak memasang apa-apa untuk anda.

Perkara yang diminta oleh wizard persediaan, dan perkara yang ditulisnya

Sehingga Ogos 2026, discourse-setup hanyalah pembalut (wrapper) nipis. Ia menjalankan discourse/setup-wizard:release sebagai kontena dengan rangkaian hos dan soket Docker yang dilekapkan (mounted), supaya wizard boleh memeriksa mesin yang sedang dikonfigurasikannya. Ia meminta nama hos dan alamat e-mel pentadbir, kemudian meminta blok SMTP anda. Ia menulis containers/app.yml, kemudian membina semula (rebuild).

Dua gelagat perlu diketahui sebelum anda bermula. Jika mesin kekurangan memori dan tiada swap, wizard akan berhenti dan menawarkan untuk menciptanya: pembalut tersebut kemudian akan membuat /swapfile bersaiz 2 GB, menambahkannya ke /etc/fstab, menetapkan vm.swappiness = 10 dalam /etc/sysctl.d/30-discourse-swap.conf, dan memulakan semula wizard. Apabila wizard selesai, ia mencetak Rebuilding app in 5 seconds (Ctrl+C to cancel)... dan menjalankan ./launcher rebuild app pada hos. Proses binaan itu mengambil masa beberapa minit pada VPS kecil, dan binaan pertama adalah yang paling perlahan kerana setiap aset dikompilasi dari awal.

./discourse-setup --help menyenaraikan flag yang penting apabila berlaku masalah. --skip-rebuild menulis konfigurasi tanpa membina, dan --skip-connection-test melangkau pemeriksaan DNS dan port. Gunakan --skip-connection-test hanya apabila anda sudah tahu sebab ujian gagal, contohnya apabila hos berada di belakang firewall rangkaian yang anda kawal.

Baca app.yml sebelum bina semula kali pertama

Wizard akan menulis fail yang kini menjadi tanggungjawab anda untuk diselenggara. Buka fail tersebut dengan sudo nano /var/discourse/containers/app.yml. Bahagian-bahagian ini menentukan hampir segala-galanya.

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 ialah alamat yang digunakan oleh tapak tersebut untuk menjawab permintaan, dan Discourse membina pautan daripadanya. Nilai yang salah akan menyebabkan tapak dimuatkan sekali sahaja dan kemudian menghalakan anda ke tempat lain. DISCOURSE_DEVELOPER_EMAILS ialah senarai yang dipisahkan dengan koma, dan alamat-alamat tersebut akan menjadi pentadbir secara automatik semasa pendaftaran pertama. Letakkan alamat anda sendiri di sana dan daftar dengannya, kerana itulah cara akaun pentadbir pertama dicipta.

Fail ini menyimpan kata laluan SMTP anda dalam teks biasa, jadi hadkan akses direktori tersebut dengan sudo chmod 700 /var/discourse/containers. Ia juga merupakan YAML, yang bermaksud ruang putih (whitespace) adalah konfigurasi: kunci yang tidak sejajar akan menyebabkan proses binaan gagal dengan ralat penghuraian (parse error) dan menyebabkan tapak anda tidak dapat diakses. Satu perangkap telah didokumentasikan dalam fail contoh itu sendiri. # di dalam kata laluan yang tidak bertanda petikan akan memulakan ulasan (comment), jadi letakkan tanda petikan pada mana-mana kata laluan yang mengandungi simbol tersebut.

E-mel merupakan langkah yang paling kerap menghentikan pemasangan

Sehingga Ogos 2026, wizard membolehkan anda melangkau SMTP dan menggunakan log masuk Discourse ID sebagai ganti, dan app.yml membawa suis DISCOURSE_SKIP_EMAIL_SETUP yang sepadan, yang diterangkan di sana sebagai melangkau pengesahan tetapan e-mel. Melangkau langkah ini adalah munasabah untuk tinjauan awal perisian tersebut. Ia merupakan pilihan yang kurang baik untuk komuniti, kerana tanpa mel keluar, tiada sesiapa boleh mengaktifkan akaun atau menetapkan semula kata laluan.

Masalah praktikalnya ialah kebanyakan penyedia VPS menyekat port 25 keluar, jadi pelayan mel biasa pada mesin tersebut tidak akan menghantar e-mel. Gunakan relay yang disahkan pada port 587, atau pada 465 dengan TLS (transport layer security) tersirat. Untuk 465, tetapkan DISCOURSE_SMTP_FORCE_TLS: true, yang disyorkan oleh konfigurasi contoh untuk port tersebut. Uji kebolehcapaian dari hos sebelum anda membina semula.

nc -vz smtp.example.com 587

Hasil yang baik ialah satu baris yang berakhir dengan succeeded!. Perintah yang tergantung dan kemudian tamat masa bermakna port tersebut disekat pada laluan keluar VPS anda, dan tiada tetapan Discourse yang dapat membetulkannya. Beralih ke port yang dibenarkan oleh penyedia anda, atau minta penyedia untuk membukanya.

Setelah tapak tersebut aktif, hantar mesej ujian dari halaman E-mel dalam Admin, kemudian baca tab Skipped dan Bounced pada halaman yang sama. Tab tersebut adalah tempat Discourse merekodkan mel yang enggan dihantar dan mel yang ditolak oleh relay, dan ia menyatakan sebabnya, yang lebih pantas daripada membaca log.

TLS: biarkan kontena mendapatkan sijilnya sendiri

Jika Discourse menguasai port 80 dan 443, gunakan fungsi pengeluaran sijil terbina dalamnya. Nyahkomen dua baris templat SSL yang ditunjukkan di atas, kemudian lakukan binaan semula (rebuild). Templat tersebut memacu acme.sh, menyimpan sijil dalam volum kongsi di bawah /shared/ssl, memperbaharuinya mengikut jadual di dalam kontena, dan menetapkan Discourse untuk memaksa HTTPS.

Port 80 mesti kekal boleh dicapai dari internet supaya proses ini berfungsi, kerana cabaran HTTP dijawab di sana. Firewall yang hanya membenarkan port 443 akan menyebabkan binaan selesai tetapi sijil tidak akan dikeluarkan. Semak hasilnya dengan ./launcher logs app sejurus selepas binaan semula.

Patutkah anda meletakkan nginx atau Caddy di hadapan?

Jika Discourse merupakan satu-satunya servis web pada VPS, jangan lakukannya. Kontena tersebut sudah menjalankan nginx yang ditala, dan proksi kedua akan menambah satu hop, satu lagi sijil untuk diperbaharui, serta punca baharu bagi pepijat pengepala (header).

Letakkannya di hadapan apabila VPS yang sama melayani tapak web lain. Tambahkan templates/web.socketed.template.yml ke dalam senarai templat, komenkan kedua-dua baris expose, dan biarkan dua templat SSL tersebut dalam keadaan dikomen. Kontena tersebut kemudiannya akan mendengar pada unix socket di /var/discourse/shared/standalone/nginx.http.sock dan tidak memegang sebarang port, yang membebaskan port 80 dan 443 untuk proksi 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 bertindih di hujung selepas .sock adalah sebahagian daripada sintaks unix socket nginx, dan sudo nginx -t akan menolak konfigurasi tersebut tanpanya. X-Forwarded-Proto juga bukan pilihan. Discourse menulis pautan mutlak, jadi tanpa pengepala tersebut ia akan mengeluarkan pautan http:// pada halaman HTTPS, dan pelayar akan menyekatnya sebagai kandungan bercampur (mixed content). Dengan kontena yang menggunakan socket, TLS menjadi tanggungjawab anda, jadi keluarkan sijil pada hos dengan Certbot pada Ubuntu 24.04 dan nginx. Jika anda belum membuat keputusan mengenai proksi, perbandingan nginx, Caddy dan Traefik merangkumi pertukaran yang anda lakukan.

Binaan semula, naik taraf dan arahan yang akan anda gunakan

cd /var/discourse
./launcher rebuild app

rebuild memusnahkan kontena yang sedang berjalan, memulakan kontena baharu daripada app.yml, dan menjalankannya. Laman web akan berada dalam keadaan luar talian sepanjang proses binaan, jadi anggap setiap perubahan konfigurasi sebagai waktu henti berjadual selama beberapa minit.

Perubahan nilai di bawah env: sahaja tidak memerlukan proses tersebut. ./launcher destroy app && ./launcher start app mencipta semula kontena daripada imej yang telah anda bina, yang hanya mengambil masa beberapa saat. Sebarang perubahan di bawah templates: atau hooks: akan mengubah imej itu sendiri, maka ia memerlukan binaan semula sepenuhnya.

Naik taraf diterima melalui dua cara. Keluaran titik (point releases) digunakan daripada antara muka web di /admin/upgrade, yang disediakan oleh pemalam docker_manager yang diklon oleh app.yml semasa proses binaan. Perubahan pada imej asas atau templat datang daripada git.

cd /var/discourse
git pull
./launcher rebuild app

Binaan semula merupakan punca kegagalan pelayan bersaiz kecil, kerana penyusunan aset (asset compilation) merupakan kemuncak penggunaan memori bagi keseluruhan sistem. Binaan yang terhenti di tengah jalan, dengan dmesg memaparkan baris seperti Out of memory: Killed process yang menamakan proses ruby, bermakna sistem kehabisan memori semasa binaan walaupun laman web tersebut berjalan dengan lancar sebelumnya. Tambahkan swap dan jalankan semula binaan tersebut.

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

logs mencetak output kontena, enter membuka shell di dalamnya, dan cleanup membuang kontena yang telah dihentikan selama lebih daripada 24 jam. Jalankan cleanup dari semasa ke semasa, kerana setiap binaan semula akan meninggalkan kontena lama dan ruang cakera pada VPS bersaiz kecil akan kehabisan secara senyap.

Sandaran, dan fail yang tidak terkandung dalam sandaran

Ambil sandaran daripada halaman Backups dalam Admin. Arkib tersebut akan disimpan pada hos di /var/discourse/shared/standalone/backups/default/. Tugasan yang sama boleh dijalankan daripada shell.

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

discourse restore <filename> akan menyongsangkan proses tersebut, dan pemulihan (restore) akan ditolak sehingga anda menjalankan discourse enable_restore. Langkah keselamatan ini wujud supaya arahan yang tersilap tidak menimpa forum yang sedang aktif.

Terdapat dua jurang yang perlu anda tutup sendiri. Arkib tersebut menyimpan pangkalan data, dan ia hanya menyimpan fail yang dimuat naik apabila tetapan sandaran yang merangkumi muat naik diaktifkan, jadi semak tetapan tersebut sebelum anda mempercayainya. Ia tidak pernah menyimpan app.yml, jadi pemulihan ke VPS baharu masih memerlukan hostname dan blok SMTP anda, yang bermaksud anda perlu menyalin fail tersebut keluar dari pelayan itu juga.

Arkib tersebut juga terletak pada cakera yang sama dengan tapak yang dilindunginya, yang bukanlah satu sandaran sebenar. Pindahkan ia ke lokasi lain mengikut jadual.

rsync -avz root@forum.example.com:/var/discourse/shared/standalone/backups/default/ ~/discourse-backups/

Kos RAM untuk forum yang sibuk

Bootstrap menetapkan UNICORN_WORKERS dan db_shared_buffers berdasarkan memori dan CPU yang dikesan, dan konfigurasi contoh mengehadkan shared buffers kepada satu perempat daripada jumlah memori. Setiap pekerja unicorn ialah proses Ruby yang penuh, dan Sidekiq menjalankan tugasan latar belakang di sampingnya, jadi penggunaan memori mengikut permintaan serentak dan bukannya bilangan ahli yang berdaftar. Forum yang sunyi dengan beberapa ratus ahli bukanlah beban kerja yang berat. Apa lagi yang berkongsi pelayan biasanya lebih penting, dan jika itu adalah pustaka foto, lantai RAM yang diukur dalam perbandingan PhotoPrism dan Immich akan memberitahu anda sama ada binaan semula Discourse masih mempunyai ruang yang cukup untuk selesai.

Jangan tentukan saiz pelayan berdasarkan nombor dalam artikel, termasuk artikel ini. Ukur sendiri.

free -m
docker stats --no-stream

Swap yang sentiasa digunakan bersama halaman yang perlahan bermakna anda kekurangan RAM. Memori yang stabil dengan halaman yang perlahan biasanya bermakna sesuatu yang lain, jadi baca ./launcher logs app sebelum membeli pelan yang lebih besar. Tambahkan semakan dari luar pelayan juga, kerana forum yang kehabisan memori pada pukul 3 pagi akan gagal secara senyap: pemantau status Uptime Kuma yang dihoskan sendiri pada hos yang berasingan memberitahu anda sebelum ahli anda menyedarinya.

Apabila Discourse bukan pilihan yang tepat

Discourse ialah aplikasi berskala besar dengan proses pemasangan yang berat serta kitaran bina semula (rebuild) bagi setiap tetapan yang berada dalam app.yml. Kos tersebut memberikan alat penyederhanaan (moderation) yang sebenar serta fungsi carian yang tetap berkesan walaupun arkib sudah besar. Bagi tiga puluh orang yang mahukan ruang untuk berbual, ia adalah sistem yang terlalu kompleks untuk keperluan perbualan tersebut. Baca perbandingan perisian forum yang dihoskan sendiri terlebih dahulu, dan pilih Discourse kerana anda mahukan fungsi yang ditawarkannya, bukan kerana ia adalah nama yang anda sudah kenali.

FAQ

Bolehkah saya memasang Discourse pada VPS tanpa nama domain?

Tidak. Konfigurasi yang dibekalkan menyatakan bahawa Discourse tidak akan berfungsi dengan alamat IP sahaja, dan DISCOURSE_HOSTNAME diperlukan. Discourse membina pautan mutlak daripada hostname tersebut, jadi penggunaan alamat IP akan merosakkan pautan dan menghalang pengeluaran sijil. Cipta rekod A sebelum anda bermula, dan sahkan dengan dig +short forum.example.com bahawa ia diselesaikan kepada alamat pelayan anda.

Adakah saya perlu mengkonfigurasi SMTP untuk melengkapkan pemasangan?

Sehingga Ogos 2026, anda boleh melangkau langkah ini. Wizard persediaan menawarkan log masuk Discourse ID sebagai ganti, dan app.yml mempunyai suis yang melangkau pengesahan persediaan e-mel. Untuk penggunaan selain daripada percubaan awal, konfigurasikannya kerana pengaktifan akaun dan tetapan semula kata laluan kedua-duanya dihantar melalui e-mel. Gunakan relay berautentikasi pada port 587 atau 465, memandangkan kebanyakan penyedia VPS menyekat trafik keluar port 25.

Mengapa proses bina semula (rebuild) Discourse saya gagal di pertengahan jalan?

Memori biasanya menjadi punca. Kompilasi aset semasa proses binaan memerlukan lebih banyak memori berbanding tapak yang sedang berjalan, jadi pelayan yang mampu mengendalikan forum dengan baik mungkin masih gagal semasa proses bina semula. Jika dmesg menunjukkan Out of memory: Killed process yang merujuk kepada proses ruby, tambahkan swap (swapfile lalai wizard ialah 2 GB) dan jalankan ./launcher rebuild app sekali lagi. Binaan yang terhenti pada ralat YAML pula menunjukkan kesilapan indentasi dalam app.yml.

Patutkah Discourse diletakkan di belakang nginx atau Caddy saya sendiri?

Hanya jika VPS tersebut turut menghoskan tapak lain. Jika ia bersendirian pada pelayan, biarkan kontena mengekalkan port 80 dan 443 serta mengeluarkan sijilnya sendiri, yang mengurangkan komponen yang perlu diurus. Untuk berkongsi mesin, tambahkan templates/web.socketed.template.yml, komen baris expose, dan lakukan proksi ke unix socket pada /var/discourse/shared/standalone/nginx.http.sock. Luluskan X-Forwarded-Proto, atau Discourse akan mengeluarkan pautan http:// pada halaman HTTPS.

Bagaimanakah cara untuk membuat sandaran (backup) Discourse yang dihoskan sendiri?

Gunakan halaman Backups dalam Admin, atau jalankan discourse backup selepas ./launcher enter app. Arkib akan disimpan pada hos di /var/discourse/shared/standalone/backups/default/. Sahkan tetapan yang menyertakan muat naik telah diaktifkan, salin /var/discourse/containers/app.yml bersama arkib tersebut, dan pindahkan kedua-duanya ke mesin lain, kerana sandaran pada cakera yang sama dengan tapak tidak akan terselamat daripada kegagalan yang sepatutnya ia lindungi.