Cara Pasang Discourse di VPS Menggunakan Docker
Ketahui cara pasang Discourse di VPS dengan Docker launcher rasmi. Panduan ini merangkumi penyediaan RAM, swap, SMTP, konfigurasi app.yml, serta proses binaan semula.
Memasang Discourse pada VPS: satu kontena, satu fail konfigurasi
Untuk memasang Discourse pada VPS, anda perlu menjalankan pemasang projek tersebut, menjawab wizard ringkas, 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 kemudian terletak dalam satu fail, /var/discourse/containers/app.yml, dan setiap perubahan akan diaplikasikan pada laman tersebut melalui proses binaan semula.
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 bertujuan 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 sebelum memulakan Discourse
Terdapat empat keperluan yang sering terlepas pandang, dan setiap satunya akan menjadi penghalang 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. Contoh konfigurasi yang dibekalkan menyatakan dengan jelas: "Discourse tidak akan berfungsi dengan alamat IP sahaja."
- Laluan mel keluar. Pengaktifan akaun, tetapan semula kata laluan, jemputan pentadbir 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 sedia ada.
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 pada 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 oleh 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.coKedua-dua arahan mesti memaparkan alamat yang sama. Ia perlu sepadan kerana wizard persediaan akan 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 dan jangan cuba memintas 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) 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 bashJika Docker sudah tersedia pada pelayan dan anda lebih gemar 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-setupJalankan 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.
Apa yang diminta oleh wizard persediaan, dan apa yang ditulisnya
Sehingga Ogos 2026 discourse-setup hanyalah pembungkus (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 dikonfigurasikan. Ia meminta nama hos dan alamat e-mel pentadbir, kemudian blok SMTP anda. Ia menulis containers/app.yml, kemudian membina semula.
Dua kelakuan perlu diketahui sebelum anda bermula. Jika mesin kekurangan memori dan tiada swap, wizard akan berhenti dan menawarkan untuk menciptanya: pembungkus tersebut kemudian 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. Binaan tersebut mengambil masa beberapa minit pada VPS kecil, dan binaan pertama adalah yang paling perlahan kerana setiap aset disusun (compiled) 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 mengetahui punca kegagalan ujian, contohnya apabila hos berada di belakang firewall rangkaian yang anda kawal.
Baca app.yml sebelum bina semula kali pertama
Wizard akan menulis satu 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 dengan sudo chmod 700 /var/discourse/containers. Ia juga merupakan YAML, yang bermaksud ruang putih adalah konfigurasi: kunci yang tidak sejajar akan menyebabkan binaan gagal dengan ralat penghuraian (parse error) dan menyebabkan tapak anda tidak berfungsi. Satu perangkap didokumenkan dalam fail contoh itu sendiri. # di dalam kata laluan yang tidak bertanda petikan akan memulakan komen, jadi letakkan tanda petikan pada mana-mana kata laluan yang mengandungi simbol tersebut.
E-mel merupakan langkah yang paling kerap menghalang 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 percubaan awal perisian tersebut. Ia merupakan pilihan yang kurang baik untuk komuniti, kerana tanpa mel keluar, tiada sesiapa yang 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 587Hasil 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 daripada halaman E-mel dalam Admin, kemudian baca tab Skipped dan Bounced pada halaman yang sama. Tab tersebut merupakan 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 penggunaan HTTPS.
Port 80 mesti kekal boleh dicapai dari internet supaya proses ini berfungsi, kerana cabaran HTTP dijawab di situ. 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 selesai.
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 itu kemudiannya akan mendengar pada soket unix 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 soket unix 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 soket, 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 apprebuild memusnahkan kontena yang sedang berjalan, memulakan kontena baharu daripada app.yml, dan menjalankannya. Laman web akan berada di 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 appBinaan semula merupakan punca kegagalan pelayan 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 berjalan dengan lancar sebelumnya. Tambahkan swap dan jalankan semula binaan tersebut.
./launcher logs app
./launcher enter app
./launcher cleanuplogs memaparkan 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 kecil akan kehabisan tanpa disedari.
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 backupdiscourse restore <filename> akan menyongsangkan proses tersebut, dan pemulihan (restore) akan ditolak sehingga anda menjalankan discourse enable_restore. Langkah kawalan 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 dihidupkan, jadi semak tetapan tersebut sebelum anda mempercayainya. Ia tidak pernah menyimpan app.yml, jadi pemulihan ke VPS baharu masih memerlukan nama hos dan blok SMTP anda, yang bermaksud anda perlu menyalin fail tersebut keluar dari pelayan itu juga.
Arkib tersebut juga berada 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 worker 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.
Jangan tentukan saiz pelayan berdasarkan nombor dalam artikel, termasuk artikel ini. Ukur keperluan anda sendiri.
free -m
docker stats --no-streamSwap yang sentiasa digunakan bersama halaman yang perlahan bermakna anda kekurangan RAM. Memori yang stabil dengan halaman yang perlahan biasanya bermaksud masalah lain, jadi baca ./launcher logs app sebelum membeli pelan yang lebih besar. Tambahkan pemeriksaan dari luar pelayan juga, kerana forum yang kehabisan memori pada pukul 3 pagi akan gagal secara senyap: monitor status Uptime Kuma yang dihoskan sendiri pada hos berasingan akan 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 anda alat penyederhanaan (moderation) yang sebenar serta fungsi carian yang tetap berkesan walaupun arkib sudah besar. Bagi tiga puluh orang yang hanya 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 sudah anda 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 nama hos 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 yang disahkan pada port 587 atau 465, memandangkan kebanyakan penyedia VPS menyekat port 25 keluar.
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 masih boleh gagal semasa proses bina semula. Jika dmesg menunjukkan Out of memory: Killed process yang menamakan proses ruby, tambah swap (fail swap yang disediakan oleh wizard adalah 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, kerana ini mengurangkan komponen yang perlu diurus. Untuk berkongsi mesin, tambah templates/web.socketed.template.yml, komen baris expose, dan lakukan proksi ke soket unix di /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 yang berada pada cakera yang sama dengan tapak tidak akan terselamat daripada kegagalan yang sepatutnya ia lindungi.