העלאה לאוויר (Deployment)
שרת שרץ רק על המחשב שלכם הוא עדיין תרגיל. בשיעור האחרון נכין את ה-API לפרודקשן ונעלה אותו לשירות אחסון, כך שכל אחד יוכל לפנות אליו מכתובת אמיתית.
להכין את הקוד
// src/server.js
import { app } from './app.js';
const port = Number(process.env.PORT) || 3000; // שירותי אחסון קובעים את הפורט בעצמם
const server = app.listen(port, () => console.log(`השרת רץ בפורט ${port}`));
// כשהשירות מכבה או מחליף גרסה: לסיים בקשות פתוחות לפני יציאה
process.on('SIGTERM', () => {
console.log('מקבל SIGTERM, סוגר את השרת...');
server.close(() => process.exit(0));
});
- PORT מהסביבה - אף פעם לא פורט קבוע בפרודקשן.
NODE_ENV=production- Express ורוב הספריות עובדים מהר יותר ומסתירים פרטים פנימיים.- Health check - נתיב פשוט שהשירות בודק כדי לדעת שהשרת חי:
app.get('/health', (req, res) => res.json({ status: 'ok' }));
package.json מוכן לפרודקשן
{
"name": "todo-api",
"type": "module",
"engines": { "node": ">=22" },
"scripts": {
"dev": "node --watch --env-file=.env src/server.js",
"start": "node src/server.js",
"test": "node --test"
}
}
שירותי אחסון מריצים npm install ואז npm start. בפרודקשן אין קובץ .env: את המשתנים מגדירים בממשק של השירות.
איפה לאחסן
| סוג | דוגמאות | מתאים ל |
|---|---|---|
| פלטפורמה מנוהלת (PaaS) | Render, Railway, Fly.io | הדרך הקלה: מחברים את ה-GitHub, והשירות בונה ומעלה בכל push |
| Serverless | Vercel, Netlify Functions, Cloud Functions | API קטן עם עומס לא קבוע. דורש התאמה של המבנה |
| שרת וירטואלי (VPS) | DigitalOcean, Hetzner, AWS EC2 | שליטה מלאה, אבל אתם אחראים לעדכונים, HTTPS ואבטחה |
העלאה לפלטפורמה מנוהלת, שלב אחר שלב
- דחפו את הקוד ל-GitHub (ודאו ש-
.envו-node_modulesב-.gitignore). - בשירות, צרו "Web Service" חדש וחברו את המאגר.
- Build command:
npm ci. Start command:npm start. - הגדירו משתני סביבה:
NODE_ENV=production,DATABASE_URL,JWT_SECRET. - צרו מסד נתונים מנוהל (רוב השירותים מציעים PostgreSQL או MySQL), והעתיקו את כתובת החיבור ל-
DATABASE_URL. - אחרי ההעלאה, בדקו את
/healthבכתובת שקיבלתם.
npm ci מתקין בדיוק את מה שב-package-lock.json, ולכן חובה לשמור את הקובץ הזה ב-Git.
מאחורי Proxy
בכל השירותים האלה, הבקשה עוברת דרך Proxy לפני שהיא מגיעה לשרת שלכם. בלי הגדרה, Express יחשוב שכל הבקשות מגיעות מאותה כתובת, והגבלת הקצב תחסום את כולם יחד:
app.set('trust proxy', 1); // סומכים על Proxy אחד לפני השרת
Docker: אותה סביבה בכל מקום
Docker אורז את השרת עם הגרסה המדויקת של Node.js, כך שהוא רץ אותו דבר אצלכם, אצל חבר לצוות ובשרת:
# Dockerfile
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY src ./src
ENV NODE_ENV=production
EXPOSE 3000
USER node
CMD ["node", "src/server.js"]
docker build -t todo-api .
docker run -p 3000:3000 --env-file .env todo-api
--omit=dev- בלי חבילות פיתוח, כדי שה-image יהיה קטן.USER node- לא להריץ כ-root, שכבת הגנה נוספת.- קובץ
.dockerignoreעםnode_modulesו-.env, כדי שהם לא ייכנסו ל-image.
אחרי שהשרת באוויר
- לוגים - כל שירות מציג את מה ש-
console.logמדפיס. לפרויקט רציני: ספריית לוגים כמו pino. - ניטור שגיאות - שירות כמו Sentry מתריע כשמשהו נשבר, עם כל הפרטים.
- גיבויים - ודאו שמסד הנתונים מגובה אוטומטית.
- עדכונים -
npm auditושדרוג תלויות באופן קבוע.
סיימתם את המסלול
עברתם מ"שלום עולם" ב-Node.js עד API מאובטח, עם מסד נתונים, משתמשים ושרת באוויר. זה הבסיס של רוב מערכות ה-Backend. הצעד הטבעי הבא: לחבר אליו ממשק ב-React, ולהעמיק ב-SQL.
בדקו את עצמכם
נסו לענות לבד לפני שאתם פותחים את התשובה.
-
מה תפקיד נתיב
/health?הצגת התשובה
תשובה א. אם הבדיקה נכשלת, השירות מפעיל את השרת מחדש.
-
למה
app.set('trust proxy', 1)מאחורי שירות אחסון?הצגת התשובה
תשובה ד. בלי זה כל הבקשות נראות כאילו הגיעו מה-Proxy.
-
למה
npm ciבשרת ולאnpm install?הצגת התשובה
תשובה א. כך מה שנבדק אצלכם הוא מה שרץ בפרודקשן.