מודול 2 · בשרת — שיעור 3 מתוך 5

תהליכים, פורטים והרשאות

11 דקות קריאה

התחברו כדי שההתקדמות בקורס תישמר בחשבון.

התהליך הוא המכולה

בשרת, האפליקציה שלכם היא תהליך עם PID. כל מה שמסביב — systemd, Docker, PM2 — קיים כדי להחזיר אותו לחיים אם הוא מת, ולהעביר אליו בקשות.

להאזין נכון

app.listen(port, "0.0.0.0", () => log(`listening on ${port}`));

0.0.0.0 = כל הממשקים. 127.0.0.1 = רק המכונה עצמה (מתאים כשפרוקסי יושב על אותה מכונה). אם האפליקציה מאזינה ל-127.0.0.1 ומגיעה בקשה מבחוץ — היא תתקבל בידי הפרוקסי ולא תמצא את מי לענות.

SIGTERM: לכבות יפה

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

process.on("SIGTERM", async () => {
  server.close(async () => {
    await db.close();
    process.exit(0);
  });
  setTimeout(() => process.exit(1), 10_000).unref();   // לא להיתקע לנצח
});

זה מה שהופך פריסה ל"אפס השבתה" בפועל: השרת הישן מפסיק לקבל בקשות חדשות, מסיים את מה שהתחיל, ורק אז מת.

PID 1

במכולה, התהליך הראשון הוא PID 1. ל-PID 1 בלינוקס אין טיפול ברירת מחדל באותות, ולכן CMD ["npm","start"] הוא בעיה: npm הוא PID 1 ומקבל את האות במקום Node. לכן:

CMD ["node", "server.js"]

או docker run --init, שמוסיף תהליך init קטן שמטפל באותות ובזומבים.

הרשאות

  • לא להריץ כ-root. משתמש ייעודי עם הרשאה רק לתיקיית האפליקציה.
  • קבצים מוגנים: .env בהרשאות 600.
  • פורטים מתחת ל-1024 דורשים הרשאה מיוחדת — עדיף פרוקסי (nginx/Caddy/Traefik) שמאזין ל-443 ומעביר ל-3000.

משאבים: להגביל כדי לא ליפול

docker run --memory=512m --cpus=1 --restart=unless-stopped myapp

בלי הגבלה, אפליקציה עם דליפת זיכרון תאכל את כל השרת ותפיל גם את בסיס הנתונים. עם הגבלה — היא נופלת לבד, ו-restart מחזיר אותה, והשרת נשאר בחיים.