SSD Nodes Learn 🎉 VPS החל מ־$5.50/חודש
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-13

התקנת Discourse על שרת VPS באמצעות Docker

למדו כיצד להתקין Discourse על שרת VPS עם Docker. המדריך מפרט את הגדרות ה-RAM הנדרשות, עריכת קובץ app.yml, הגדרת SMTP, ניהול תעודות TLS וביצוע תהליך ה-rebuild המלא.

התקנת Discourse על שרת VPS: מכולה אחת, קובץ הגדרות אחד

כדי להתקין Discourse על שרת VPS, יש להריץ את תוכנית ההתקנה של הפרויקט, לענות על אשף קצר ולהמתין לבנייה. Discourse מופץ כמכולת Docker יחידה המכילה את יישום ה-Rails, את PostgreSQL, את Redis ואת nginx. כל שינוי שתבצעו בהמשך מתבצע בקובץ אחד, /var/discourse/containers/app.yml, וכל שינוי מוחל על האתר באמצעות בנייה מחדש.

ההתקנה הרשמית היא discourse_docker: סקריפט shell מסוג launcher בצירוף קבוצת תבניות YAML. Discourse אינו תומך בקובץ Compose שכותבים באופן עצמאי, והמכולה אינה מיועדת לפירוק ידני. אם אתם רגילים ל-הרצת שירותים על VPS באמצעות Docker Compose, צפו למבנה שונה. אין כאן docker compose up -d, ו-./launcher rebuild app הוא תהליך הפריסה.

דרישות קדם להתקנת Discourse

ארבע דרישות עלולות להכשיל אתכם, וכל אחת מהן תמנע מכם להגיע לדף ההתחברות אם לא תטופל מראש.

  • זיכרון (RAM). מכולה אחת מריצה את PostgreSQL, Redis, Sidekiq ושרת אינטרנט מבוסס Ruby. שלב ה-build מהדר קבצים וצורך זיכרון רב יותר מאשר האתר בזמן פעילות שוטפת.
  • שם מתחם (Domain) אמיתי. קובץ התצורה לדוגמה מציין זאת במפורש: "Discourse לא יעבוד עם כתובת IP בלבד".
  • נתיב דואר יוצא. הפעלת חשבונות, איפוס סיסמאות, הזמנות מנהלים וסיכומי דואר – כולם נשלחים באמצעות SMTP (פרוטוקול העברת דואר פשוט).
  • פורטים 80 ו-443 פנויים במארח, אלא אם בחרתם במכוון להריץ את Discourse מאחורי proxy קיים.
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 עבור שם המארח (hostname) שבו תשתמשו, ולאחר מכן ודאו את תקינותה מתוך השרת עצמו.

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

שתי הפקודות חייבות להציג את אותה כתובת. עליהן להיות מסונכרנות, כיוון שאשף ההתקנה מריץ בדיקת חיבור מול שם המארח שלכם; רשומה שעדיין מצביעה למקום אחר תגרום לכישלון הבדיקה. רשומה שיצרתם לפני שתי דקות עשויה להיות עדיין ב-cache, לכן המתינו לסיום ה-TTL (זמן חיים) הישן במקום להיאבק באשף.

החליטו כעת האם הרשומה תעבור דרך CDN. רשומה שעוברת דרך proxy מסתירה את כתובת השרת שלכם, ובמקרה כזה בקשת התעודה של המכולה תיכשל, כיוון שה-ACME (סביבת ניהול תעודות אוטומטית) נענית על ידי ה-proxy ולא על ידי Discourse. השאירו את הרשומה ללא proxy עבור ההתקנה הראשונית.

הרצת המתקין הרשמי

פקודה אחת מתקינה את git, מתקינה את Docker באמצעות סקריפט ההתקנה של Docker עצמו, משכפלת את discourse_docker לתוך /var/discourse, ומפעילה את אשף ההגדרה.

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., כיוון שהשכפול הידני לא מתקין עבורכם דבר.

מה שואל אשף ההתקנה, ומה הוא כותב

נכון לאוגוסט 2026, discourse-setup הוא מעטפת דקה. הוא מריץ את discourse/setup-wizard:release כמכולה (container) עם רשת המארח (host network) ועם ה-socket של Docker ממופה, כדי שהאשף יוכל לבחון את המכונה שהוא מגדיר. הוא מבקש את שם המארח (hostname) וכתובות הדוא"ל של מנהל המערכת, ולאחר מכן את פרטי ה-SMTP שלכם. הוא כותב את containers/app.yml, ואז מבצע בנייה מחדש.

כדאי להכיר שני דפוסי התנהגות לפני שמתחילים. אם למכונה חסר זיכרון ואין בה swap, האשף עוצר ומציע ליצור אותו: המעטפת יוצרת אז קובץ /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 על המארח. בנייה זו אורכת מספר דקות ב-VPS קטן, והבנייה הראשונה היא האיטית ביותר מכיוון שכל הנכסים עוברים הידור (compile) מאפס.

./discourse-setup --help מפרט את הדגלים (flags) החשובים כאשר משהו משתבש. --skip-rebuild כותב את קובץ התצורה ללא ביצוע בנייה, ו---skip-connection-test מדלג על בדיקות ה-DNS והפורטים. השתמשו ב---skip-connection-test רק כאשר אתם כבר יודעים מדוע הבדיקה נכשלת, למשל כאשר המארח נמצא מאחורי firewall רשתי שאתם מנהלים.

קראו את app.yml לפני ה-rebuild הראשון

אשף ההתקנה יוצר קובץ שמעתה ואילך נמצא באחריותכם. פתחו אותו באמצעות 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 הוא הכתובת שבה האתר מגיב, ו-Discourse בונה את הקישורים שלו על פיה; ערך שגוי יגרום לאתר להיטען פעם אחת בלבד ואז להפנות אתכם למקום אחר. DISCOURSE_DEVELOPER_EMAILS הוא רשימה מופרדת בפסיקים, וכתובות אלו מקבלות הרשאות מנהל (admin) באופן אוטומטי בעת ההרשמה הראשונה. הזינו שם את כתובת האימייל שלכם והירשמו איתה, שכן כך נוצר חשבון המנהל הראשון.

הקובץ שומר את סיסמת ה-SMTP שלכם בטקסט גלוי, לכן הגבילו את הגישה לתיקייה באמצעות sudo chmod 700 /var/discourse/containers. הקובץ הוא בפורמט YAML, מה שאומר שרווחים הם חלק מהתצורה: מפתח שאינו מיושר כראוי יגרום לכשל ב-build עם שגיאת ניתוח (parse error) וישאיר אתכם ללא אתר פעיל. מלכודת אחת מתועדת בתוך קובץ הדוגמה עצמו. תו # בתוך סיסמה שאינה במירכאות מתחיל הערה, לכן הקפידו להקיף במירכאות כל סיסמה המכילה תו כזה.

דואר אלקטרוני הוא השלב שבו רוב ההתקנות נתקעות

נכון לאוגוסט 2026, אשף ההתקנה מאפשר לדלג על הגדרת SMTP ולהשתמש במקום זאת בהתחברות דרך Discourse ID, והפקודה app.yml כוללת את ה-switch התואם DISCOURSE_SKIP_EMAIL_SETUP, המתואר שם כביטול אימות הגדרות הדואר. דילוג על שלב זה סביר עבור התרשמות ראשונית מהתוכנה. זוהי בחירה גרועה עבור קהילה פעילה, כיוון שללא דואר יוצא, משתמשים לא יוכלו להפעיל חשבונות או לאפס סיסמאות.

הבעיה המעשית היא שרוב ספקי ה-VPS חוסמים את פורט 25 לתעבורה יוצאת, ולכן שרת דואר פשוט על השרת לא יצליח לשלוח הודעות. השתמשו ב-relay מאומת בפורט 587, או בפורט 465 עם 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 דחה, והן מציינות את סיבת הכישלון, מה שמהיר יותר מקריאת לוגים.

TLS: אפשר למכולה להנפיק לעצמה תעודה

אם Discourse מאזין לפורטים 80 ו-443, השתמשו במנגנון ההנפקה המובנה שלו. בטלו את ההערה בשורות ה-template של ה-SSL המוצגות לעיל, ולאחר מכן בצעו rebuild. ה-template מפעיל את acme.sh, שומר תעודות בנפח המשותף תחת /shared/ssl, מחדש אותן לפי לוח זמנים בתוך המכולה, ומגדיר את Discourse לאכיפת HTTPS.

פורט 80 חייב להישאר נגיש מהאינטרנט כדי שתהליך זה יצליח, שכן אתגר ה-HTTP נענה שם. firewall שמאפשר גישה לפורט 443 בלבד יגרום לכך שה-build יסתיים, אך התעודה לעולם לא תונפק. בדקו את התוצאה באמצעות ./launcher logs app מיד לאחר ה-rebuild.

האם כדאי להציב Nginx או Caddy בחזית?

אם Discourse הוא שירות האינטרנט היחיד בשרת ה-VPS, אל תעשו זאת. המכולה כבר מריצה מופע Nginx מכוונן, ו-proxy נוסף רק מוסיף שלב בדרך, תעודה נוספת לחידוש ומקור חדש לתקלות ב-headers.

הציבו proxy בחזית רק כאשר ה-VPS משרת אתרים נוספים. הוסיפו את templates/web.socketed.template.yml לרשימת ה-templates, הפכו את שתי שורות ה-expose להערה, והשאירו את שני ה-templates של ה-SSL כהערות. המכולה תאזין כעת ל-unix socket בנתיב /var/discourse/shared/standalone/nginx.http.sock ולא תחזיק אף פורט, מה שיפנה את פורטים 80 ו-443 עבור ה-proxy שלכם.

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

הנקודתיים בסוף .sock הן חלק מתחביר ה-unix socket של Nginx, ו-sudo nginx -t יסרב לטעון את התצורה בלעדיהן. גם X-Forwarded-Proto אינו אופציונלי. Discourse מייצר קישורים מוחלטים, לכן ללא ה-header הזה הוא יפיק קישורי http:// בדף HTTPS, והדפדפנים יחסמו אותם כתוכן מעורב (mixed content). כאשר המכולה עובדת מול socket, הטיפול ב-TLS הופך לאחריותכם; לכן, הנפיקו את התעודה במכונה המארחת לפי המדריך Certbot on Ubuntu 24.04 and nginx. אם טרם החלטתם באיזה proxy לבחור, המדריך the nginx, Caddy and Traefik comparison מפרט את השיקולים והפשרות הכרוכים בכל בחירה.

בנייה מחדש, שדרוגים והפקודות שבאמת תשתמשו בהן

cd /var/discourse
./launcher rebuild app

הפקודה rebuild משמידה את המכולה הרצה, מאתחלת מכולה חדשה מתוך app.yml ומפעילה אותה. האתר אינו זמין במהלך כל תהליך הבנייה, לכן יש להתייחס לכל שינוי בתצורה כאל השבתה מתוכננת של מספר דקות.

שינוי ערכים תחת env: בלבד אינו דורש זאת. הפקודה ./launcher destroy app && ./launcher start app יוצרת מחדש את המכולה מה-image שכבר בניתם, פעולה שנמשכת שניות ספורות. כל שינוי תחת templates: או hooks: משנה את ה-image עצמו, ולכן מחייב בנייה מחדש מלאה.

שדרוגים מגיעים בשתי דרכים. גרסאות נקודה (point releases) מיושמות דרך ממשק האינטרנט ב-/admin/upgrade, המסופק על ידי התוסף docker_manager ש-app.yml משכפל (clones) במהלך הבנייה. שינויים ב-image הבסיס או בתבניות מגיעים מ-git.

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

בנייה מחדש היא הנקודה שבה שרתים קטנים נכשלים, כיוון שקימפול הנכסים (assets) הוא שיא צריכת הזיכרון של המערכת כולה. בנייה שנעצרת באמצע, כאשר dmesg מציג שורה כמו Out of memory: Killed process המציינת תהליך ruby, סבלה ממחסור בזיכרון במהלך הבנייה, גם אם האתר עצמו פעל היטב לפני כן. הוסיפו swap והריצו את הבנייה מחדש.

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

הפקודה logs מדפיסה את הפלט של המכולה, enter פותחת shell בתוכה, ו-cleanup מסירה מכולות שנעצרו לפני יותר מ-24 שעות. הריצו את cleanup מדי פעם, כיוון שכל בנייה מחדש מותירה מאחוריה מכולה ישנה, והדיסק ב-VPS קטן עלול להתמלא בשקט.

גיבויים, והקובץ שהגיבוי אינו מכיל

בצעו גיבויים מדף ה-Backups בתוך ה-Admin. הארכיון נשמר על המארח בנתיב /var/discourse/shared/standalone/backups/default/. אותה משימה ניתנת להרצה גם מה-shell.

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 שהוא מזהה, וקובץ התצורה לדוגמה מגביל את ה-shared buffers לרבע מסך הזיכרון. כל worker של unicorn הוא תהליך Ruby מלא, ו-Sidekiq מריץ משימות רקע לצדם, לכן צריכת הזיכרון נגזרת ממספר הבקשות המקביליות ולא ממספר המשתמשים הרשומים. פורום שקט עם כמה מאות משתמשים אינו מהווה עומס עבודה כבד.

אל תקבעו את גודל השרת על סמך מספר המופיע במאמר, כולל מאמר זה. מדדו את הנתונים שלכם בעצמכם.

free -m
docker stats --no-stream

שימוש קבוע ב-swap יחד עם דפים איטיים מעיד על מחסור ב-RAM. זיכרון יציב עם דפים איטיים מעיד בדרך כלל על בעיה אחרת, לכן קראו את ./launcher logs app לפני שאתם משדרגים לחבילה גדולה יותר. הוסיפו גם בדיקה מחוץ לשרת, כיוון שפורום שנגמר לו הזיכרון בשעה 3 לפנות בוקר קורס בשקט: ניטור סטטוס באמצעות Uptime Kuma על שרת נפרד יתריע לכם על כך לפני שהמשתמשים ידווחו על התקלה.

מתי Discourse אינו הבחירה הנכונה

Discourse הוא יישום גדול בעל התקנה כבדה ומחזור בנייה מחדש (rebuild) עבור כל הגדרה השמורה ב-app.yml. עלות זו מקנה כלי ניהול קהילה אמיתיים ומנוע חיפוש שמתפקד היטב גם כאשר הארכיון גדול. עבור שלושים אנשים שרוצים מקום לנהל בו שיחות, מדובר במערכת גדולה מדי לצרכי השיחה. קראו תחילה את השוואת תוכנות הפורומים לאירוח עצמי, ובחרו ב-Discourse כי אתם זקוקים ליכולות שלו, ולא רק כי זה השם שהכרתם מראש.

FAQ

האם ניתן להתקין Discourse על VPS ללא שם מתחם?

לא. התצורה המופצת קובעת ש־Discourse לא תעבוד עם כתובת IP בלבד, ונדרש DISCOURSE_HOSTNAME. המערכת בונה קישורים מוחלטים על בסיס שם המארח, לכן שימוש בכתובת IP ישבור קישורים וימנע הנפקת תעודות. צרו רשומת A לפני תחילת העבודה, וודאו באמצעות dig +short forum.example.com שהיא מתרגמת לכתובת השרת שלכם.

האם חובה להגדיר SMTP כדי לסיים את ההתקנה?

נכון לאוגוסט 2026, ניתן לדלג על כך. אשף ההתקנה מציע התחברות באמצעות Discourse ID כחלופה, ו־app.yml כולל דגל המדלג על אימות הגדרות הדואר. לכל שימוש מעבר להתרשמות ראשונית, יש להגדיר SMTP, כיוון שאימות חשבונות ואיפוס סיסמאות מתבצעים באמצעות דואר אלקטרוני. השתמשו ב־relay מאומת בפורט 587 או 465, שכן רוב ספקי ה־VPS חוסמים תעבורה יוצאת בפורט 25.

מדוע תהליך ה-rebuild של Discourse נכשל באמצע?

הסיבה הנפוצה היא מחסור בזיכרון. הידור (compilation) של נכסים במהלך הבנייה דורש יותר זיכרון מאשר הרצת האתר עצמו, לכן שרת שמריץ את הפורום היטב עלול להיכשל בבנייה מחדש. אם dmesg מציג Out of memory: Killed process המצביע על תהליך ruby, הוסיפו swap (קובץ ה-swap של האשף הוא בגודל 2 GB) והריצו את ./launcher rebuild app שוב. בנייה שנעצרת בשל שגיאת YAML מעידה על טעות בהזחה (indentation) בתוך app.yml.

האם כדאי להציב את Discourse מאחורי Nginx או Caddy משלי?

רק אם ה-VPS משרת אתרים נוספים. אם השרת מוקדש ל-Discourse בלבד, הניחו למכולה להחזיק בפורטים 80 ו-443 ולהנפיק לעצמה תעודות; כך תצמצמו את מספר הרכיבים. כדי לשתף את המכונה, הוסיפו את templates/web.socketed.template.yml, הגיבו (comment out) את השורות של expose, ובצעו proxy ל-unix socket בכתובת /var/discourse/shared/standalone/nginx.http.sock. העבירו את X-Forwarded-Proto, אחרת Discourse תפיק קישורי http:// בדף HTTPS.

כיצד מגבים התקנת Discourse עצמאית?

השתמשו בדף הגיבויים (Backups) בממשק הניהול, או הריצו את discourse backup לאחר ./launcher enter app. הארכיונים נשמרים במארח בנתיב /var/discourse/shared/standalone/backups/default/. ודאו שההגדרה הכוללת העלאות (uploads) פעילה, העתיקו את /var/discourse/containers/app.yml יחד עם הארכיון, והעבירו את שניהם למכונה אחרת; גיבוי שנמצא על אותו דיסק של האתר לא ישרוד את הכשל שלשמו הוא נועד.