SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-28

วิธีติดตั้ง Discourse บน VPS ด้วย Docker แบบเป็นขั้นตอน

เรียนรู้วิธีติดตั้ง Discourse บน VPS ด้วย Docker อย่างถูกต้องตามมาตรฐาน ครอบคลุมการตั้งค่า app.yml การจัดการ RAM และ Swap การตั้งค่า SMTP รวมถึงขั้นตอนการ rebuild เพื่อเปิดใช้งาน TLS

การติดตั้ง Discourse บน VPS: หนึ่งคอนเทนเนอร์ หนึ่งไฟล์คอนฟิก

ในการติดตั้ง Discourse บน VPS คุณต้องรันตัวติดตั้งของโปรเจกต์ ตอบคำถามในวิซาร์ดสั้นๆ แล้วรอการ build Discourse มาในรูปแบบ Docker container เดียวที่รวมแอปพลิเคชัน Rails, PostgreSQL, Redis และ nginx ไว้ด้วยกัน ทุกสิ่งที่คุณจะแก้ไขในภายหลังจะอยู่ในไฟล์เดียวคือ /var/discourse/containers/app.yml และทุกการเปลี่ยนแปลงจะมีผลกับเว็บไซต์ผ่านการ rebuild

การติดตั้งอย่างเป็นทางการคือ discourse_docker ซึ่งประกอบด้วยเชลล์สคริปต์ launcher และชุดเทมเพลต YAML Discourse ไม่รองรับไฟล์ Compose ที่คุณเขียนขึ้นเอง และคอนเทนเนอร์ไม่ได้ถูกออกแบบมาให้แยกส่วนด้วยตนเอง หากคุณคุ้นเคยกับ การรันบริการบน VPS ด้วย Docker Compose ให้เตรียมพบกับรูปแบบที่แตกต่างออกไป ที่นี่ไม่มี docker compose up -d และ ./launcher rebuild app คือขั้นตอนการ deploy

สิ่งที่ Discourse ต้องการก่อนเริ่มต้น

มีข้อกำหนด 4 ประการที่มักทำให้ผู้ใช้ติดปัญหา ซึ่งแต่ละข้อจะส่งผลก่อนที่คุณจะเข้าถึงหน้าล็อกอิน

  • หน่วยความจำ: คอนเทนเนอร์หนึ่งตัวต้องรันทั้ง PostgreSQL, Redis, Sidekiq และเว็บเซิร์ฟเวอร์ Ruby ขั้นตอนการ build จะมีการคอมไพล์ assets ซึ่งต้องการหน่วยความจำมากกว่าการรันเว็บไซต์ตามปกติ
  • ชื่อโดเมนจริง: ไฟล์ config ตัวอย่างที่มาพร้อมกับซอฟต์แวร์ระบุไว้อย่างชัดเจนว่า "Discourse จะไม่ทำงานหากใช้เพียงหมายเลข IP"
  • เส้นทางสำหรับส่งอีเมลขาออก: การเปิดใช้งานบัญชี, การรีเซ็ตรหัสผ่าน, คำเชิญผู้ดูแลระบบ และอีเมลสรุปเนื้อหา ทั้งหมดต้องส่งผ่าน SMTP (Simple Mail Transfer Protocol)
  • พอร์ต 80 และ 443 ต้องว่างบนโฮสต์ เว้นแต่คุณจะตั้งใจย้าย Discourse ไปไว้หลังพร็อกซีที่คุณใช้งานอยู่แล้ว
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
  }
]

เอกสารการติดตั้งอย่างเป็นทางการกำหนดขั้นต่ำไว้ที่ 1 GB ของ RAM พร้อม swap และ 10 GB ของพื้นที่ดิสก์ และแนะนำที่ 2 GB ของ RAM พร้อมกับ 20 GB ของพื้นที่ดิสก์ โปรดอ่านค่าในแถวแรกว่าเป็นตัวเลขที่ช่วยให้การติดตั้งเสร็จสมบูรณ์ ไม่ใช่ตัวเลขที่คุณต้องการเพื่อใช้รันชุมชนจริง ช่องว่างระหว่างค่าเหล่านี้มีความสำคัญเนื่องจากจุดที่ใช้หน่วยความจำสูงสุดคือช่วงการ build ไม่ใช่ช่วงที่มีการใช้งานจริง

ชี้โดเมนมาที่เซิร์ฟเวอร์ก่อนเริ่มติดตั้ง

สร้าง A record สำหรับ hostname ที่คุณจะใช้งาน จากนั้นตรวจสอบความถูกต้องจากตัวเซิร์ฟเวอร์เอง

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

คำสั่งทั้งสองต้องแสดงผลเป็น IP address เดียวกัน ทั้งสองต้องตรงกันเนื่องจากตัวช่วยติดตั้งจะทำการทดสอบการเชื่อมต่อกับ hostname ของคุณ หาก record ยังชี้ไปยังที่อื่น การทดสอบจะล้มเหลว A record ที่คุณเพิ่งสร้างเมื่อ 2 นาทีก่อนอาจยังอยู่ใน cache ดังนั้นให้รอจนกว่าค่า TTL (time to live) เดิมจะหมดอายุ แทนที่จะพยายามแก้ไขปัญหาที่ตัวช่วยติดตั้ง

ตัดสินใจให้แน่ชัดว่า record นี้จะถูกส่งผ่าน CDN หรือไม่ หาก record ถูกส่งผ่าน CDN จะเป็นการซ่อน IP address ของเซิร์ฟเวอร์คุณ ซึ่งจะทำให้การร้องขอ certificate ของ container ล้มเหลว เนื่องจากกระบวนการ ACME (automatic certificate management environment) จะถูกตอบกลับโดย proxy แทนที่จะเป็น Discourse ให้ตั้งค่า record แบบไม่ผ่าน proxy สำหรับการติดตั้งครั้งแรก

เรียกใช้ตัวติดตั้งอย่างเป็นทางการ

คำสั่งเดียวจะทำการติดตั้ง git, ติดตั้ง Docker ด้วยสคริปต์การติดตั้งของ Docker เอง, ทำการ clone discourse_docker ไปยัง /var/discourse และเริ่มตัวช่วยตั้งค่า (setup wizard)

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

หากมี Docker อยู่บนเครื่องแล้วและคุณต้องการดูแต่ละขั้นตอนด้วยตนเอง ให้ดำเนินการตามขั้นตอนเหล่านั้นด้วยตัวเอง

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

เรียกใช้คำสั่งในฐานะ root หากเริ่มการทำงานด้วยผู้ใช้ทั่วไป discourse-setup จะหยุดทำงานทันทีพร้อมกับ This script must be run as root. Please sudo or log in as root first. หากไม่มี Docker อยู่บนเครื่อง ระบบจะหยุดทำงานพร้อมกับ Docker is not installed. Please install Docker first. เนื่องจากขั้นตอนการ clone ด้วยตนเองไม่ได้ติดตั้งสิ่งใดให้คุณ

สิ่งที่ตัวช่วยติดตั้งถามและสิ่งที่เขียนลงในไฟล์

ณ เดือนสิงหาคม 2026 discourse-setup เป็นเพียง wrapper ขนาดเล็ก มันจะรัน discourse/setup-wizard:release ในรูปแบบคอนเทนเนอร์โดยใช้ host network และ mount Docker socket เข้าไป เพื่อให้ตัวช่วยติดตั้งสามารถตรวจสอบเครื่องที่กำลังตั้งค่าอยู่ได้ ระบบจะถามชื่อโฮสต์และที่อยู่อีเมลของผู้ดูแลระบบ จากนั้นจะถามข้อมูลบล็อก SMTP ของคุณ แล้วจึงเขียนไฟล์ containers/app.yml และทำการ build ใหม่

มีพฤติกรรมสองอย่างที่ควรทราบก่อนเริ่ม หากเครื่องมีหน่วยความจำไม่เพียงพอและไม่มี swap ตัวช่วยติดตั้งจะหยุดทำงานและเสนอให้สร้าง swap ขึ้นมา โดย wrapper จะสร้างไฟล์ /swapfile ขนาด 2 GB เพิ่มเข้าไปใน /etc/fstab ตั้งค่า vm.swappiness = 10 ใน /etc/sysctl.d/30-discourse-swap.conf แล้วจึงเริ่มตัวช่วยติดตั้งใหม่อีกครั้ง เมื่อตัวช่วยติดตั้งเสร็จสิ้น ระบบจะแสดง Rebuilding app in 5 seconds (Ctrl+C to cancel)... และรัน ./launcher rebuild app บนโฮสต์ กระบวนการ build นี้ใช้เวลาหลายนาทีบน VPS ขนาดเล็ก และการ build ครั้งแรกจะช้าที่สุดเนื่องจากสินทรัพย์ทุกอย่างต้องถูกคอมไพล์ใหม่ทั้งหมด

./discourse-setup --help แสดงรายการแฟล็กที่สำคัญเมื่อเกิดปัญหาขึ้น --skip-rebuild จะเขียนไฟล์คอนฟิกโดยไม่ทำการ build และ --skip-connection-test จะข้ามการตรวจสอบ DNS และพอร์ต ให้ใช้ --skip-connection-test เฉพาะเมื่อคุณทราบสาเหตุที่การทดสอบล้มเหลวแล้วเท่านั้น เช่น กรณีที่โฮสต์อยู่หลัง network firewall ที่คุณเป็นผู้ควบคุมเอง

อ่านไฟล์ app.yml ก่อนการสร้างใหม่ครั้งแรก

วิซาร์ดจะสร้างไฟล์ที่คุณต้องเป็นผู้ดูแลต่อจากนี้ เปิดไฟล์ดังกล่าวด้วย sudo nano /var/discourse/containers/app.yml ส่วนประกอบเหล่านี้คือสิ่งที่กำหนดการทำงานเกือบทั้งหมด

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 คือที่อยู่ (address) ที่เว็บไซต์จะตอบสนอง และ Discourse จะใช้ค่านี้ในการสร้างลิงก์ต่างๆ ดังนั้นหากระบุค่าผิดพลาด เว็บไซต์จะโหลดได้เพียงครั้งเดียวแล้วเปลี่ยนเส้นทางคุณไปยังที่อื่น DISCOURSE_DEVELOPER_EMAILS คือรายการที่คั่นด้วยเครื่องหมายจุลภาค (comma) โดยที่อยู่ที่ระบุในนี้จะได้รับสิทธิ์ผู้ดูแลระบบโดยอัตโนมัติเมื่อลงทะเบียนครั้งแรก ให้ใส่ที่อยู่อีเมลของคุณลงไปและใช้ลงทะเบียน เพราะนั่นคือวิธีสร้างบัญชีผู้ดูแลระบบบัญชีแรก

ไฟล์นี้จะเก็บรหัสผ่าน SMTP ของคุณในรูปแบบข้อความธรรมดา (plain text) ดังนั้นควรจำกัดสิทธิ์การเข้าถึงไดเรกทอรีด้วย sudo chmod 700 /var/discourse/containers ไฟล์นี้เป็นรูปแบบ YAML ซึ่งหมายความว่าช่องว่าง (whitespace) คือส่วนหนึ่งของการตั้งค่า หากคีย์ไม่ตรงแนวจะทำให้การ build ล้มเหลวด้วยข้อผิดพลาดในการแยกวิเคราะห์ (parse error) และส่งผลให้เว็บไซต์ใช้งานไม่ได้ มีกับดักหนึ่งที่ระบุไว้ในไฟล์ตัวอย่าง คือการใช้เครื่องหมาย # ภายในรหัสผ่านที่ไม่ได้ใส่เครื่องหมายคำพูดจะถือเป็นการเริ่มคอมเมนต์ ดังนั้นให้ใส่เครื่องหมายคำพูดครอบรหัสผ่านที่มีเครื่องหมายดังกล่าวเสมอ

อีเมลคือขั้นตอนที่ทำให้การติดตั้งส่วนใหญ่หยุดชะงัก

นับตั้งแต่เดือนสิงหาคม 2026 วิซาร์ดช่วยให้คุณข้ามการตั้งค่า SMTP และใช้การล็อกอินผ่าน Discourse ID แทนได้ โดยที่ app.yml จะมาพร้อมกับสวิตช์ DISCOURSE_SKIP_EMAIL_SETUP ที่สอดคล้องกัน ซึ่งระบุไว้ว่าเป็นการข้ามการตรวจสอบการตั้งค่าอีเมล การข้ามขั้นตอนนี้ถือว่าสมเหตุสมผลสำหรับการทดลองใช้งานซอฟต์แวร์ในเบื้องต้น แต่เป็นทางเลือกที่ไม่ดีนักสำหรับการสร้างชุมชน เนื่องจากหากไม่มีการส่งอีเมลออก ผู้ใช้จะไม่สามารถเปิดใช้งานบัญชีหรือรีเซ็ตรหัสผ่านได้

ปัญหาในทางปฏิบัติคือผู้ให้บริการ VPS ส่วนใหญ่บล็อกพอร์ต 25 สำหรับขาออก ทำให้เมลเซิร์ฟเวอร์ทั่วไปที่ติดตั้งบนเครื่องไม่สามารถส่งอีเมลได้ ให้ใช้ authenticated relay บนพอร์ต 587 หรือพอร์ต 465 ที่ใช้ implicit TLS (transport layer security) สำหรับพอร์ต 465 ให้ตั้งค่า DISCOURSE_SMTP_FORCE_TLS: true ซึ่งเป็นค่าที่ไฟล์ตัวอย่างแนะนำให้ใช้สำหรับพอร์ตดังกล่าว ให้ทดสอบการเชื่อมต่อจากโฮสต์ก่อนที่คุณจะทำการ rebuild

nc -vz smtp.example.com 587

ผลลัพธ์ที่ปกติคือบรรทัดเดียวที่ลงท้ายด้วย succeeded! หากคำสั่งค้างและหมดเวลา (timeout) แสดงว่าพอร์ตถูกบล็อกระหว่างทางออกจาก VPS ของคุณ และไม่มีการตั้งค่าใดใน Discourse ที่จะแก้ไขปัญหานี้ได้ ให้เปลี่ยนไปใช้พอร์ตที่ผู้ให้บริการอนุญาต หรือติดต่อผู้ให้บริการเพื่อขอเปิดพอร์ต

เมื่อเว็บไซต์เริ่มทำงานแล้ว ให้ส่งข้อความทดสอบจากหน้า Email ในส่วน Admin จากนั้นตรวจสอบแท็บ Skipped และ Bounced ในหน้าเดียวกัน แท็บเหล่านี้คือที่ที่ Discourse บันทึกอีเมลที่ปฏิเสธการส่งและอีเมลที่ relay ปฏิเสธรับ โดยจะระบุสาเหตุไว้ ซึ่งช่วยให้ตรวจสอบได้รวดเร็วกว่าการอ่าน log

TLS: ให้คอนเทนเนอร์จัดการใบรับรองด้วยตนเอง

หาก Discourse เป็นผู้ดูแลพอร์ต 80 และ 443 ให้ใช้ระบบออกใบรับรองที่มีมาให้ในตัว ให้ยกเลิกการคอมเมนต์บรรทัดเทมเพลต SSL สองบรรทัดที่แสดงไว้ด้านบน จากนั้นทำการ rebuild เทมเพลตนี้จะควบคุม acme.sh, จัดเก็บใบรับรองไว้ใน shared volume ที่ /shared/ssl, ต่ออายุใบรับรองตามกำหนดเวลาภายในคอนเทนเนอร์ และตั้งค่าให้ Discourse บังคับใช้ HTTPS

พอร์ต 80 ต้องสามารถเข้าถึงได้จากอินเทอร์เน็ตเพื่อให้กระบวนการนี้ทำงานได้ เนื่องจากต้องใช้ตอบรับ HTTP challenge หากไฟร์วอลล์อนุญาตเฉพาะพอร์ต 443 จะทำให้การ build เสร็จสิ้นแต่ใบรับรองจะไม่ถูกออกให้ ตรวจสอบผลลัพธ์ด้วย ./launcher logs app ทันทีหลังจาก rebuild เสร็จสิ้น

ควรวาง Nginx หรือ Caddy ไว้ด้านหน้าหรือไม่

หาก Discourse เป็นบริการเว็บเดียวบน VPS ไม่จำเป็นต้องทำเช่นนั้น เนื่องจากคอนเทนเนอร์ได้รัน Nginx ที่ปรับแต่งมาแล้ว การเพิ่มพร็อกซีตัวที่สองจะเพิ่มขั้นตอนการรับส่งข้อมูล เพิ่มภาระในการต่ออายุใบรับรอง และอาจทำให้เกิดปัญหาเรื่อง header ได้

ควรวางพร็อกซีไว้ด้านหน้าก็ต่อเมื่อ VPS เครื่องเดียวกันนั้นให้บริการเว็บไซต์อื่นด้วย ให้เพิ่ม templates/web.socketed.template.yml เข้าไปในรายการ templates จากนั้นให้ใส่เครื่องหมายคอมเมนต์หน้าบรรทัด expose ทั้งสองบรรทัด และปล่อยให้ SSL template ทั้งสองบรรทัดถูกคอมเมนต์ไว้อย่างนั้น คอนเทนเนอร์จะเปลี่ยนไปฟังคำขอผ่าน unix socket ที่ /var/discourse/shared/standalone/nginx.http.sock แทน และจะไม่เปิดพอร์ตใดๆ เลย ซึ่งจะช่วยให้พอร์ต 80 และ 443 ว่างสำหรับพร็อกซีของคุณ

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;
  }
}

เครื่องหมายทวิภาค (colon) ต่อท้าย .sock เป็นส่วนหนึ่งของไวยากรณ์ unix socket ของ Nginx และ sudo nginx -t จะปฏิเสธการตั้งค่าหากไม่มีเครื่องหมายดังกล่าว ส่วน X-Forwarded-Proto ก็จำเป็นต้องมีเช่นกัน เนื่องจาก Discourse เขียนลิงก์แบบสัมบูรณ์ (absolute links) หากไม่มี header นี้ ระบบจะสร้างลิงก์แบบ http:// บนหน้า HTTPS ซึ่งจะทำให้เบราว์เซอร์บล็อกการเชื่อมต่อเนื่องจากเป็นเนื้อหาแบบผสม (mixed content) เมื่อคอนเทนเนอร์ทำงานผ่าน socket การจัดการ TLS จึงกลายเป็นหน้าที่ของคุณ ดังนั้นให้ดำเนินการออกใบรับรองบนโฮสต์ตามขั้นตอนใน Certbot บน Ubuntu 24.04 และ Nginx หากคุณยังไม่ได้ตัดสินใจเลือกพร็อกซี การเปรียบเทียบ Nginx, Caddy และ Traefik จะช่วยให้คุณเข้าใจถึงข้อดีและข้อเสียในการตัดสินใจเลือกใช้งาน

การสร้างใหม่ การอัปเกรด และคำสั่งที่คุณจะได้ใช้งานจริง

cd /var/discourse
./launcher rebuild app

rebuild จะทำลายคอนเทนเนอร์ที่กำลังทำงานอยู่ สร้างคอนเทนเนอร์ใหม่จาก app.yml แล้วเริ่มการทำงานใหม่ เว็บไซต์จะออฟไลน์ตลอดช่วงเวลาที่สร้างใหม่ ดังนั้นให้ถือว่าการเปลี่ยนแปลงการตั้งค่าทุกครั้งคือการหยุดให้บริการตามกำหนดการเป็นเวลาสองสามนาที

การเปลี่ยนเฉพาะค่าภายใต้ env: ไม่จำเป็นต้องทำเช่นนั้น ./launcher destroy app && ./launcher start app จะสร้างคอนเทนเนอร์ขึ้นใหม่จากอิมเมจที่คุณสร้างไว้แล้ว ซึ่งใช้เวลาเพียงไม่กี่วินาที การเปลี่ยนแปลงใดๆ ภายใต้ templates: หรือ hooks: จะส่งผลต่อตัวอิมเมจโดยตรง จึงจำเป็นต้องสร้างใหม่ทั้งหมด

การอัปเกรดมีสองวิธี การอัปเกรดเวอร์ชันย่อย (point release) สามารถทำได้จากหน้าเว็บที่ /admin/upgrade โดยอาศัยปลั๊กอิน docker_manager ที่ app.yml ทำการโคลนมาในระหว่างการสร้าง ส่วนการเปลี่ยนแปลงอิมเมจหลักหรือเทมเพลตจะมาจาก git

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

การสร้างใหม่เป็นจุดที่เซิร์ฟเวอร์ขนาดเล็กมักจะล้มเหลว เนื่องจากขั้นตอนการคอมไพล์แอสเซท (asset compilation) เป็นช่วงที่ระบบใช้หน่วยความจำสูงสุด หากการสร้างหยุดลงกลางคันโดยที่ dmesg แสดงบรรทัดที่คล้ายกับ Out of memory: Killed process ซึ่งระบุถึงกระบวนการ ruby แสดงว่าหน่วยความจำไม่เพียงพอในระหว่างการสร้าง แม้ว่าเว็บไซต์จะทำงานได้ตามปกติก่อนหน้านี้ก็ตาม ให้เพิ่ม swap แล้วทำการสร้างใหม่ซ้ำอีกครั้ง

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

logs ใช้สำหรับแสดงผลลัพธ์จากคอนเทนเนอร์ enter ใช้สำหรับเปิดเชลล์ภายในคอนเทนเนอร์ และ cleanup ใช้สำหรับลบคอนเทนเนอร์ที่หยุดทำงานมานานกว่า 24 ชั่วโมง ควรเรียกใช้ cleanup เป็นระยะ เนื่องจากทุกครั้งที่มีการสร้างใหม่ ระบบจะทิ้งคอนเทนเนอร์เก่าไว้ ซึ่งอาจทำให้พื้นที่ดิสก์บน VPS ขนาดเล็กเต็มไปอย่างเงียบๆ

การสำรองข้อมูลและไฟล์ที่ไม่ได้รวมอยู่ในการสำรองข้อมูล

ให้ทำการสำรองข้อมูลจากหน้า Backups ในส่วน Admin ไฟล์ที่ได้จะถูกจัดเก็บไว้บนโฮสต์ที่ /var/discourse/shared/standalone/backups/default/ คุณสามารถรันงานเดียวกันนี้ผ่านเชลล์ได้เช่นกัน

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

discourse restore <filename> จะทำหน้าที่ย้อนกลับกระบวนการดังกล่าว และการกู้คืนข้อมูลจะถูกปฏิเสธจนกว่าคุณจะรัน discourse enable_restore กลไกป้องกันนี้มีไว้เพื่อไม่ให้คำสั่งที่ผิดพลาดเขียนทับข้อมูลฟอรัมที่กำลังใช้งานอยู่

มีช่องว่างสองประการที่คุณต้องจัดการด้วยตนเอง ไฟล์สำรองจะเก็บฐานข้อมูลไว้ และจะเก็บไฟล์ที่อัปโหลดไว้ก็ต่อเมื่อเปิดการตั้งค่าการสำรองข้อมูลที่รวมไฟล์อัปโหลดไว้ด้วยเท่านั้น ดังนั้นควรตรวจสอบการตั้งค่าดังกล่าวก่อนที่จะเชื่อมั่นในข้อมูลสำรองนั้น นอกจากนี้ ไฟล์สำรองจะไม่เก็บ app.yml ไว้ ดังนั้นการกู้คืนข้อมูลลงบน VPS เครื่องใหม่ยังคงต้องใช้ชื่อโฮสต์และการตั้งค่า SMTP ของคุณ ซึ่งหมายความว่าคุณต้องคัดลอกไฟล์ดังกล่าวออกมาจากเครื่องด้วยเช่นกัน

ไฟล์สำรองยังคงถูกจัดเก็บไว้บนดิสก์ลูกเดียวกับเว็บไซต์ที่ต้องการป้องกัน ซึ่งถือว่าไม่ใช่การสำรองข้อมูลที่ปลอดภัย คุณควรตั้งเวลาเพื่อคัดลอกไฟล์เหล่านั้นไปยังที่อื่น

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

ต้นทุนด้าน RAM ของฟอรัมที่มีผู้ใช้งานหนาแน่น

กระบวนการ bootstrap จะตั้งค่า UNICORN_WORKERS และ db_shared_buffers ตามหน่วยความจำและ CPU ที่ตรวจพบ โดยตัวอย่างไฟล์ config จะจำกัด shared buffers ไว้ที่หนึ่งในสี่ของหน่วยความจำทั้งหมด worker ของ unicorn แต่ละตัวคือกระบวนการ Ruby เต็มรูปแบบ และ Sidekiq จะรันงานเบื้องหลังควบคู่กันไป ดังนั้นการใช้หน่วยความจำจึงแปรผันตามจำนวนคำขอที่เกิดขึ้นพร้อมกัน ไม่ใช่จำนวนสมาชิกที่ลงทะเบียนไว้ ฟอรัมที่เงียบเหงาซึ่งมีสมาชิกเพียงไม่กี่ร้อยคนไม่ใช่ภาระงานที่หนักหนา สิ่งที่แชร์ทรัพยากรอยู่บนเซิร์ฟเวอร์เดียวกันมักมีความสำคัญมากกว่า และหากเป็นคลังรูปภาพ ค่า RAM ขั้นต่ำที่วัดได้ใน การเปรียบเทียบระหว่าง PhotoPrism และ Immich จะบอกคุณได้ว่าการ rebuild ของ Discourse ยังมีพื้นที่เหลือเพียงพอให้ทำงานจนเสร็จหรือไม่

อย่ากำหนดขนาดเซิร์ฟเวอร์จากตัวเลขในบทความ รวมถึงบทความนี้ด้วย ให้ทำการวัดค่าด้วยตัวคุณเอง

free -m
docker stats --no-stream

หากมีการใช้งาน Swap ตลอดเวลาควบคู่ไปกับการโหลดหน้าเว็บที่ช้า แสดงว่า RAM ของคุณไม่เพียงพอ หากหน่วยความจำคงที่แต่หน้าเว็บยังช้า มักเกิดจากสาเหตุอื่น ดังนั้นโปรดอ่าน ./launcher logs app ก่อนตัดสินใจซื้อแพ็กเกจที่ใหญ่ขึ้น นอกจากนี้ควรเพิ่มการตรวจสอบจากภายนอกเซิร์ฟเวอร์ด้วย เพราะฟอรัมที่หน่วยความจำหมดในช่วงตี 3 จะล้มเหลวโดยไม่มีการแจ้งเตือน: การใช้ Uptime Kuma สำหรับตรวจสอบสถานะแบบ self-hosted บนโฮสต์แยกต่างหากจะแจ้งให้คุณทราบก่อนที่สมาชิกของคุณจะพบปัญหา

เมื่อ Discourse ไม่ใช่ตัวเลือกที่เหมาะสม

Discourse เป็นแอปพลิเคชันขนาดใหญ่ที่มีขั้นตอนการติดตั้งซับซ้อน และต้องทำการ rebuild ทุกครั้งที่มีการเปลี่ยนแปลงการตั้งค่าใน app.yml สิ่งที่แลกมากับความยุ่งยากนี้คือเครื่องมือจัดการเนื้อหาที่มีประสิทธิภาพและระบบค้นหาที่ยังคงทำงานได้ดีเมื่อมีข้อมูลจำนวนมาก หากคุณมีผู้ใช้งานเพียง 30 คนที่ต้องการพื้นที่สนทนา Discourse อาจเป็นระบบที่เกินความจำเป็นสำหรับความต้องการดังกล่าว โปรดอ่าน การเปรียบเทียบซอฟต์แวร์ทำฟอรัมแบบ self-hosted ก่อนตัดสินใจ และเลือกใช้ Discourse เพราะคุณต้องการฟีเจอร์ที่ระบบนี้มีให้ ไม่ใช่เพียงเพราะเป็นชื่อที่คุณคุ้นเคยอยู่แล้ว

FAQ

ฉันสามารถติดตั้ง Discourse บน VPS โดยไม่มีชื่อโดเมนได้หรือไม่?

ไม่ได้ การตั้งค่าที่มาพร้อมกับซอฟต์แวร์ระบุว่า Discourse จะไม่ทำงานหากใช้เพียงหมายเลข IP และจำเป็นต้องมี DISCOURSE_HOSTNAME Discourse จะสร้างลิงก์แบบสัมบูรณ์จากชื่อโฮสต์นั้น ดังนั้นการใช้ที่อยู่ IP จะทำให้ลิงก์เสียและขัดขวางการออกใบรับรอง ให้สร้าง A record ก่อนเริ่มติดตั้ง และตรวจสอบด้วย dig +short forum.example.com ว่าชี้ไปยังที่อยู่ของเซิร์ฟเวอร์ของคุณอย่างถูกต้อง

ฉันจำเป็นต้องตั้งค่า SMTP เพื่อให้การติดตั้งเสร็จสมบูรณ์หรือไม่?

ตั้งแต่เดือนสิงหาคม 2026 เป็นต้นไป คุณสามารถข้ามขั้นตอนนี้ได้ ตัวช่วยติดตั้งมีตัวเลือกให้ใช้การล็อกอินผ่าน Discourse ID แทน และ app.yml มีสวิตช์ที่ช่วยข้ามการตรวจสอบการตั้งค่าอีเมล อย่างไรก็ตาม หากต้องการใช้งานจริงหลังจากทดลองใช้เบื้องต้น คุณควรตั้งค่าให้เรียบร้อย เนื่องจากการเปิดใช้งานบัญชีและการรีเซ็ตรหัสผ่านต้องทำผ่านอีเมล ให้ใช้ authenticated relay บนพอร์ต 587 หรือ 465 เนื่องจากผู้ให้บริการ VPS ส่วนใหญ่บล็อกพอร์ต 25 สำหรับการส่งอีเมลขาออก

ทำไมการ rebuild ของ Discourse ถึงล้มเหลวระหว่างดำเนินการ?

สาเหตุส่วนใหญ่มักเกิดจากหน่วยความจำไม่เพียงพอ การคอมไพล์ asset ระหว่างการ build ต้องการหน่วยความจำมากกว่าการรันเว็บไซต์ปกติ ดังนั้นเซิร์ฟเวอร์ที่รันฟอรัมได้ตามปกติอาจล้มเหลวเมื่อทำการ rebuild หาก dmesg แสดง Out of memory: Killed process ที่ระบุถึงกระบวนการ ruby ให้เพิ่ม swap (swapfile ที่ตัวช่วยติดตั้งสร้างให้มีขนาด 2 GB) แล้วรัน ./launcher rebuild app อีกครั้ง หากการ build หยุดลงที่ข้อผิดพลาด YAML แสดงว่าเกิดความผิดพลาดในการเยื้องบรรทัดใน app.yml

Discourse ควรอยู่หลัง Nginx หรือ Caddy ของฉันเองหรือไม่?

ควรทำเฉพาะในกรณีที่ VPS นั้นให้บริการเว็บไซต์อื่นด้วย หากรันเพียงลำพังบนเซิร์ฟเวอร์ ให้คอนเทนเนอร์ถือพอร์ต 80 และ 443 ไว้และจัดการใบรับรองด้วยตัวเอง ซึ่งจะช่วยลดความซับซ้อนของระบบ แต่หากต้องการแชร์เครื่องร่วมกับบริการอื่น ให้เพิ่ม templates/web.socketed.template.yml, ใส่เครื่องหมายคอมเมนต์ที่บรรทัด expose และทำ proxy ไปยัง unix socket ที่ /var/discourse/shared/standalone/nginx.http.sock อย่าลืมส่งผ่าน X-Forwarded-Proto มิฉะนั้น Discourse จะสร้างลิงก์ http:// บนหน้า HTTPS

ฉันจะสำรองข้อมูล Discourse ที่โฮสต์เองได้อย่างไร?

ให้ใช้หน้า Backups ในส่วน Admin หรือรัน discourse backup หลังจาก ./launcher enter app ไฟล์สำรองจะถูกเก็บไว้ที่โฮสต์ใน /var/discourse/shared/standalone/backups/default/ ตรวจสอบให้แน่ใจว่าการตั้งค่าที่รวมไฟล์อัปโหลดถูกเปิดใช้งานอยู่ จากนั้นคัดลอก /var/discourse/containers/app.yml ไปพร้อมกับไฟล์สำรอง และย้ายทั้งสองอย่างไปยังเครื่องอื่น เนื่องจากการเก็บข้อมูลสำรองไว้บนดิสก์เดียวกับเว็บไซต์จะไม่สามารถกู้คืนได้หากดิสก์นั้นเกิดความเสียหาย