איך להגדיר אפליקציית Node.js לייצור בסביבת הפקה על Rocky Linux 9

הקדמה

Node.js הוא סביבת ריצה לשפת ג'אווהסקריפט עם קוד פתוח לבניית יישומי שרת ורשת. הפלטפורמה פועלת על Linux, macOS, FreeBSD ו-Windows. אם ניתן להפעיל אפליקציות Node.js בשורת הפקודה, המדריך הזה יתמקד בהפעלתן כשירות. זה אומר שהן ייפענו מחדש באופן אוטומטי בעת האתחול או כשיש כשלון, והן בטוחות לשימוש בסביבת ייצור.

במדריך זה, תקבל תצורה של סביבת Node.js המוכנה לייצור על שרת Rocky Linux 9 יחיד. השרת יפעיל יישום Node.js שמנוהל על ידי PM2, ויספק גישה מאובטחת למשתמשים ליישום דרך פרוקסי הפוך של Nginx. השרת Nginx יציע HTTPS באמצעות תעודה חינמית שמסופקת על ידי Let’s Encrypt.

דרישות מוקדמות

המדריך מניח שיש לך את התקנות הבאות:

כאשר תסיים את התנאים המקדימים, תהיה לך שרת שמשרת את עמוד ההפניה המותקן של הדומיין שלך ב-https://example.com/.

שלב 1 — יצירת אפליקציית Node.js

בוא נכתוב אפליקציית Hello World שמחזירה "שלום עולם" לכל בקשת HTTP. האפליקציה הדוגמא תעזור לך להתחיל ולרוץ עם Node.js. ניתן להחליף אותה באפליקציה משלך — רק וודא שאתה משנה את האפליקציה שלך כך שתקשיב לכתובות IP וליפים המתאימים.

העורך הטקסט המובנה ב-Rocky Linux 9 הוא vi. vi הוא עורך טקסט עוצמתי ביותר, אך יכול להיות מעט מסובך למשתמשים שחסרים ניסיון עם הוא. ייתכן ותרצה להתקין עורך טקסט נוח יותר כמו nano כדי לסייע בעריכת קבצי התצורה על השרת שלך ב-Rocky Linux 9:

  1. sudo dnf install nano

עכשיו, באמצעות nano או עם עורך הטקסט האהוב עליך, צור יישום דוגמה בשם hello.js:

  1. nano hello.js

הכנס את הקוד הבא לקובץ:

~/hello.js
const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

שמור את הקובץ וצא מהעורך. אם אתה משתמש ב־nano, לחץ על Ctrl+X, אז כאשר יתבקש, לחץ Y, ולאחר מכן Enter.

יישום זה של Node.js יקשיב על הכתובת והפורט שצוינו (localhost) והפורט (3000), ויחזיר "Hello World!" עם קוד הצלחת HTTP 200. מכיוון שאנו קשובים על localhost, לא יהיה ניתן לחבר לאפליקציה שלנו מלקוחות מרוחקים.

כדי לבדוק את היישום שלך, הקלד:

  1. node hello.js

תקבל את הפלט הבא:

Output
Server running at http://localhost:3000/

הערה: הרצת יישום Node.js בדרך זו תחסום פקודות נוספות עד שהיישום ייהרג באמצעות לחיצה על CTRL+C.

כדי לבדוק את היישום, פתח חלון טרמינל נוסף בשרת שלך והתחבר ל־localhost עם curl:

  1. curl http://localhost:3000

אם תקבל את הפלט הבא, היישום פועל כהלכה וקושר לכתובת ולפורט הנכונים:

Output
Hello World!

אם אין לך את הפלט שציפית, ודא שיישום Node.js פועל ומוגדר להאזין על הכתובת והפורט הנכונים.

כשאתה בטוח שהכל עובד, השכב את היישום (אם עדיין לא עשית זאת) על ידי לחיצה על CTRL+C.

שלב 2 — התקנת PM2

בואו נתקין את PM2, מנהל תהליכים עבור יישומי Node.js. PM2 מאפשר לנו להפעיל אפליקציות כשירות כך שהן ירוצו ברקע כשירות.

השתמשו ב־npm כדי להתקין את הגרסה העדכנית ביותר של PM2 בשרת שלכם:

  1. sudo npm install pm2@latest -g

האפשרות -g אומרת ל־npm להתקין את המודול באופן גלובלי, כך שהוא יהיה זמין בכל המערכת.

בואו נשתמש תחילה בפקודת pm2 start כדי להפעיל את היישום שלכם, hello.js, ברקע:

  1. pm2 start hello.js

זה גם מוסיף את היישום שלך לרשימת התהליכים של PM2, שמוצגת בכל פעם שאתם מפעילים יישום:

Output
... [PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/sammy/hello.js in fork_mode (1 instance) [PM2] Done. ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐ │ id │ name │ mode │ ↺ │ status │ cpu │ memory │ ├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤ │ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │ └────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

כפי שמצוין לעיל, PM2 מקצה באופן אוטומטי שם של היישום (מבוסס על שם הקובץ, ללא הרחבת .js) ו־id של PM2. PM2 גם מתחזקת מידע אחר, כגון PID של התהליך, המצב הנוכחי שלו ושימוש בזיכרון.

יישומים שרצים תחת PM2 יופעלו מחדש אוטומטית אם היישום קורס או נהרג, אך אנו יכולים לקחת צעד נוסף כדי להפעיל את היישום בעת האתחול של המערכת באמצעות התת־פקודה startup. תת־הפקודה הזו יוצרת ומגדירה סקריפט התחלה כדי להפעיל את PM2 ואת התהליכים שלו במשך האתחולים של השרת:

  1. pm2 startup systemd
Output
… [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

העתיקו והריצו את הפקודה המסופקת (זה כדי למנוע בעיות הרשאות בהרצת כלי Node.js כ־sudo):

  1. sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Output
… [ 'systemctl enable pm2-sammy' ] [PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service [PM2] Making script booting at startup... [PM2] [-] Executing: systemctl enable pm2-sammy... Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service. [PM2] [v] Command successfully executed. +---------------------------------------+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd

עכשיו, יהיה עליך לערוך את שירות המערכת שנוצר כדי להפוך אותו לתואם למערכת האבטחה SELinux של Rocky Linux. באמצעות nano או העורך הטקסט המועדף עליך, פתח את /etc/systemd/system/pm2-sammy.service:

  1. sudo nano /etc/systemd/system/pm2-sammy.service

בבלוק ה-[Service] של קובץ התצורה, החלף את תוכן ההגדרה של PIDFile ב-/run/pm2.pid כפי שמודגש למטה, והוסף את השורה המודגשת האחרת של Environment:

/etc/systemd/system/pm2-sammy.service
[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target

[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid

ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill

[Install]

שמור וסגור את הקובץ. עכשיו יש לך יחידת systemd שמפעילה את יחידה שלך ב-pm2 באמצעות הפעלת המחשב באמצעות hello.js.

הפעל את השירות באמצעות systemctl:

  1. sudo systemctl start pm2-sammy

בדוק את מצב יחידת systemd:

  1. systemctl status pm2-sammy

לסקירה מפורטת של systemd, יש לך אפשרות לבדוק מושגים יסודיים בנוגע ל-Systemd: עבודה עם שירותים, יחידות ויומן.

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

עצור את היישום באמצעות הפקודה הזו (ציין את שם היישום או ה-id של PM2):

  1. pm2 stop app_name_or_id

אתחל את היישום:

  1. pm2 restart app_name_or_id

רשום את היישומים שניהם ניהלים כעת על ידי PM2:

  1. pm2 list

קבל מידע על יישום ספציפי באמצעות ה-App name שלו:

  1. pm2 info app_name

הניטור של תהליכי ה-PM2 יכול להופיע על ידי הפקודה המשנית monit. זה מציג את מצב היישום, שימוש במעבד וזיכרון:

  1. pm2 monit

שים לב שהרצת pm2 בלעדיו של כל ארגומנטים תציג גם דף עזר עם דוגמאות לשימוש.

עכשיו שיישומך של Node.js רץ ונניה על ידי PM2, בוא נגדיר פרוקסי הפוך.

שלב 3 — הגדרת Nginx כשרתוך פרוקסי

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

בטוריאל המקדים, הגדרת את התצורה שלך של Nginx בקובץ /etc/nginx/conf.d/your_domain.conf. פתח את הקובץ הזה לעריכה:

  1. sudo nano /etc/nginx/conf.d/your_domain.conf

בתוך בלוק ה-server, יש לך כבר בלוק קיים של location /. החלף את תוכן הבלוק הזה עם ההגדרה הבאה. אם היישום שלך מוגדר לאזון לפי יציאה אחרת, עדכן את החלק המודגש למספר היציאה הנכון:

/etc/nginx/conf.d/your_domain.conf
server {
...
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

זה מגדיר את השרת להגיב לבקשות בשורש שלו. בהנחה שהשרת שלנו זמין ב־your_domain, גישה אל https://your_domain/ דרך דפדפן רשת תשלח את הבקשה אל hello.js, הקשיבה בפורט 3000 ב־localhost.

אפשר להוסיף בלוקי location נוספים לאותו בלוק שרת כדי לספק גישה ליישומים אחרים באותו השרת. לדוגמה, אם תפעיל גם יישום נוסף של Node.js בפורט 3001, תוכל להוסיף בלוק מיקום זה כדי לאפשר גישה אליו דרך https://your_domain/app2:

/etc/nginx/conf.d/your_domain.conf — Optional
server {
...
    location /app2 {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

כשתסיים להוסיף את בלוקי המיקום עבור היישומים שלך, שמור את הקובץ וצא מהעורך שלך.

ודא שלא הוספת טעויות תחביר על ידי הקלדת:

  1. sudo nginx -t

אתחל את Nginx מחדש:

  1. sudo systemctl restart nginx

בהנחה שיישום ה־Node.js שלך רץ, והתצורות של היישום ושל Nginx נכונות, אפשר עכשיו לגשת ליישום שלך דרך פרוקסי ההפוך של Nginx. נסה זאת על ידי גישה לכתובת ה־URL של השרת שלך (כתובת ה־IP הציבורית שלו או שם הדומיין שלו).

מסקנה

מזל טוב! כעת יש לך את היישום שלך של Node.js רץ מאחורי פרוקסי ההפוך של Nginx על שרת Rocky Linux 9. ההגדרה הזו של פרוקסי ההפוך גמישה מספיק כדי לספק למשתמשים שלך גישה ליישומים אחרים או תוכן אינטרנטי סטטי שברצונך לשתף.

הבא, ייתכן שתרצה לבדוק איך לבנות אפליקציה Node.js עם Docker.

Source:
https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-rocky-linux-9