ติดตั้ง Node.js และ PM2 บน VPS Ubuntu

Node.js คือ Runtime ที่ช่วยให้รัน JavaScript บน Server ได้ เหมาะสำหรับสร้าง API, Web App, Real-time App และ Microservice ส่วน PM2 คือ Process Manager ที่ทำให้ Node.js App รันเป็น Background Process พร้อม Auto-restart เมื่อ Server Reboot หรือ App Crash บทความนี้จะพาติดตั้งตั้งแต่ต้นจนใช้งานได้จริงบน VPS Ubuntu

ความต้องการระบบ

ขั้นตอนที่ 1: ติดตั้ง Node.js ผ่าน NVM

แนะนำให้ใช้ NVM (Node Version Manager) แทนการติดตั้งจาก apt โดยตรง เพราะจัดการหลาย Node.js version ได้ง่ายและไม่ต้องใช้ sudo ทุกครั้ง

ติดตั้ง NVM

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

รีโหลด Shell เพื่อให้คำสั่ง nvm ใช้งานได้:

source ~/.bashrc

ตรวจสอบว่า NVM ติดตั้งสำเร็จ:

nvm --version

ติดตั้ง Node.js LTS

nvm install --lts nvm use --lts nvm alias default node

ตรวจสอบ version ที่ติดตั้ง:

node -v npm -v

ทำไมต้องใช้ LTS? Node.js LTS (Long-Term Support) ได้รับ Security Patch และ Bug Fix นานกว่า 30 เดือน เหมาะสำหรับ Production Server มากกว่า Current Release

ขั้นตอนที่ 2: สร้าง Node.js App ทดสอบ

สร้างโฟลเดอร์และไฟล์ app อย่างง่าย:

mkdir -p ~/myapp && cd ~/myapp npm init -y npm install express

สร้างไฟล์ app.js:

cat > app.js << 'EOF' const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.get('/', (req, res) => { res.json({ message: 'Hello from AsiaGB VPS!', status: 'ok' }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); EOF

ทดสอบรันด้วยตรงก่อน:

node app.js

เปิดอีก Terminal แล้วทดสอบ: curl http://localhost:3000 ควรเห็น JSON Response กด Ctrl+C เพื่อหยุด

ขั้นตอนที่ 3: ติดตั้ง PM2

PM2 ทำหน้าที่เป็น Process Manager — รัน App เป็น Background, Auto-restart เมื่อ Crash และ Start อัตโนมัติเมื่อ Server Reboot

npm install -g pm2

รัน App ด้วย PM2

cd ~/myapp pm2 start app.js --name "myapp"

ดู status:

pm2 status pm2 logs myapp

ตั้ง PM2 ให้ Auto-start หลัง Reboot

pm2 startup # คัดลอกคำสั่งที่ PM2 แสดงแล้วรัน เช่น: # sudo env PATH=$PATH:/home/user/.nvm/versions/node/v20.x.x/bin pm2 startup systemd -u user --hp /home/user pm2 save

คำสั่ง PM2 ที่ใช้บ่อย: pm2 restart myapp — restart · pm2 stop myapp — หยุด · pm2 delete myapp — ลบออกจาก PM2 · pm2 monit — ดู CPU/Memory realtime

ขั้นตอนที่ 4: ตั้งค่า Nginx Reverse Proxy

Node.js รันบน Port 3000 แต่ User เข้า Port 80/443 ต้องใช้ Nginx เป็น Reverse Proxy เพื่อส่ง Request ไปยัง Node.js

ติดตั้ง Nginx

apt update && apt install nginx -y ufw allow 'Nginx Full'

สร้าง Server Block

nano /etc/nginx/sites-available/myapp

เพิ่มเนื้อหา (แทน yourdomain.com ด้วยโดเมนจริง):

server { listen 80; server_name yourdomain.com www.yourdomain.com; 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_set_header X-Real-IP $remote_addr; proxy_cache_bypass $http_upgrade; } }

Enable Site และทดสอบ config:

ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ nginx -t systemctl reload nginx

ตอนนี้เข้า http://yourdomain.com จะเห็น JSON จาก Node.js แล้ว

ขั้นตอนที่ 5: ติดตั้ง SSL ด้วย Certbot (แนะนำ)

ติดตั้ง Let's Encrypt SSL เพื่อให้ App รองรับ HTTPS:

apt install certbot python3-certbot-nginx -y certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot จะแก้ไข Nginx config ให้อัตโนมัติและตั้ง Auto-renewal ให้ด้วย

ติดตั้ง Node.js ผ่าน NodeSource (ทางเลือกแทน NVM)

หาก VPS ของคุณรันแบบ multi-user หรือมีหลาย service ที่ต้องใช้ Node.js เวอร์ชันเดียวกันทั้งระบบ การติดตั้งผ่าน NodeSource repository จะสะดวกกว่า NVM เพราะ Node.js จะอยู่ใน path ของทุก user และทำงานร่วมกับ systemd ได้ทันทีโดยไม่ต้องตั้งค่า PATH เพิ่ม วิธีนี้เหมาะกับ production server ที่ต้องการความเรียบง่ายและคาดเดาได้

ข้อแตกต่างสำคัญคือ NVM ติดตั้ง Node.js ไว้ในโฟลเดอร์ส่วนตัวของผู้ใช้ที่รันคำสั่ง ทำให้บางครั้ง service ที่รันด้วย user อื่น หรือ cron job มองไม่เห็น binary จนเกิดปัญหาเวลา deploy ขึ้นจริง ส่วน NodeSource จะวาง binary ไว้ที่ตำแหน่งกลางของระบบเสมอ ทุกกระบวนการบนเครื่องจึงเรียกใช้ได้เหมือนกัน ลดความสับสนเรื่อง path อย่างชัดเจนเมื่อทำงานบนเซิร์ฟเวอร์จริง

เพิ่ม NodeSource repo สำหรับ Node.js 20 LTS แล้วติดตั้ง:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs node -v npm -v

หากต้องการ build native module บางตัว (เช่น bcrypt, sharp) ที่ต้อง compile จาก source ให้ติดตั้ง build tools เพิ่ม:

sudo apt install -y build-essential

NVM หรือ NodeSource? ใช้ NVM เมื่อต้องสลับหลายเวอร์ชันบ่อย หรือ dev บนเครื่องเดียว · ใช้ NodeSource เมื่อต้องการ Node.js ทั้งระบบสำหรับ production และให้ systemd/PM2 หา binary เจอง่าย โดยทั่วไป production บน AsiaGB VPS ที่รัน 1 แอปต่อ 1 เครื่อง เลือก NodeSource จะดูแลง่ายกว่า

รัน App ด้วย PM2 แบบ Cluster Mode

โดย default Node.js รันบน CPU core เดียว ทำให้ใช้ทรัพยากร VPS ไม่เต็มประสิทธิภาพ PM2 มี Cluster Mode ที่ช่วยกระจาย request ไปยังหลาย process (worker) บนทุก core โดยอัตโนมัติ ผ่านโมดูล cluster ของ Node.js — ได้ทั้ง throughput ที่สูงขึ้นและ zero-downtime reload

เหตุผลที่ Node.js รันบน core เดียวเป็นค่าเริ่มต้น เพราะตัวภาษาออกแบบมาให้ทำงานแบบ single-threaded เป็นหลัก เมื่อมีผู้ใช้เข้ามาพร้อมกันจำนวนมาก process เดียวจะกลายเป็นคอขวด แม้ VPS ของคุณจะมีหลาย core ก็ตาม การเปิด cluster mode จึงเหมือนการจ้างพนักงานหลายคนมาช่วยรับงานพร้อมกัน แทนที่จะให้คนเดียวรับทุกคำสั่ง ทำให้เว็บแอปของคุณรองรับผู้ใช้ได้มากขึ้นโดยไม่ต้องเปลี่ยนโค้ดในแอปเลย และยังเป็นพื้นฐานสำคัญที่ทำให้ระบบ reload ได้แบบไม่มีช่วงดับในหัวข้อถัดไป

เริ่ม cluster โดยระบุจำนวน instance เป็น max (เท่ากับจำนวน CPU core):

pm2 start app.js --name "myapp" -i max

หรือกำหนดจำนวน worker ตายตัว เช่น 2 process (เหมาะกับ VPS 2 core):

pm2 start app.js --name "myapp" -i 2

แทนที่จะพิมพ์ flag ทุกครั้ง แนะนำให้สร้างไฟล์ ecosystem.config.js เพื่อเก็บ config ทั้งหมดไว้ที่เดียว — รวมถึง environment variable, จำนวน instance และ memory limit:

cat > ecosystem.config.js << 'EOF' module.exports = { apps: [{ name: 'myapp', script: './app.js', instances: 'max', exec_mode: 'cluster', max_memory_restart: '300M', env: { NODE_ENV: 'production', PORT: 3000 } }] }; EOF

จากนั้นสตาร์ตทั้งระบบด้วยไฟล์เดียว:

pm2 start ecosystem.config.js pm2 save

option max_memory_restart จะสั่ง restart worker อัตโนมัติเมื่อใช้ RAM เกินที่กำหนด — ช่วยป้องกัน memory leak ทำให้แอปล่มบน VPS ที่ RAM จำกัด

ข้อควรระวัง Cluster Mode: ถ้าแอปเก็บ state ไว้ใน memory (เช่น session in-memory) แต่ละ worker จะไม่แชร์ข้อมูลกัน ต้องย้าย session ไปเก็บที่ Redis หรือ database ภายนอกแทน

Monitoring, Logs และ Zero-Downtime Reload

เมื่อแอปขึ้น production แล้ว สิ่งสำคัญคือการเฝ้าดูสุขภาพ process และอัปเดตโค้ดโดยไม่ทำให้ผู้ใช้เจอ error PM2 มีเครื่องมือครบสำหรับงานนี้ การมองเห็นสถานะแอปอย่างต่อเนื่องช่วยให้คุณจับปัญหาได้ตั้งแต่เนิ่นๆ เช่น process restart บ่อยผิดปกติ หรือ memory ค่อยๆ ไต่ขึ้นเรื่อยๆ ซึ่งเป็นสัญญาณของ memory leak ก่อนที่มันจะลุกลามจนแอปล่มกลางดึก การวางระบบ monitoring และ log ที่ดีตั้งแต่แรกจึงคุ้มค่ากว่าการมาตามแก้ทีหลังมาก

ดู Resource และ Log แบบ Real-time

pm2 monit # dashboard CPU/Memory ต่อ process pm2 logs myapp # ดู log สด (stdout + stderr) pm2 logs myapp --lines 200 # ดู log ย้อนหลัง 200 บรรทัด pm2 show myapp # ดูรายละเอียด process (uptime, restarts, path)

หมุน Log ไม่ให้เต็มดิสก์

log ของ PM2 จะสะสมไปเรื่อยๆ จนเต็มดิสก์ของ VPS ได้ ติดตั้งโมดูล pm2-logrotate เพื่อหมุนและบีบอัด log อัตโนมัติ:

pm2 install pm2-logrotate pm2 set pm2-logrotate:max_size 10M pm2 set pm2-logrotate:retain 7

ค่าด้านบนคือจำกัดไฟล์ละ 10 MB และเก็บย้อนหลัง 7 ไฟล์

Zero-Downtime Reload หลังอัปเดตโค้ด

คำสั่ง restart จะหยุดทุก process พร้อมกัน ทำให้มีช่วงที่แอปดับ (downtime) สั้นๆ แต่บน cluster mode ให้ใช้ reload แทน — PM2 จะค่อยๆ replace worker ทีละตัว ขณะที่ worker ตัวอื่นยังรับ request อยู่ ผู้ใช้จึงไม่เห็น error เลย:

git pull npm install --production pm2 reload myapp

หลังตั้ง pm2 startup และ pm2 save ไว้แล้ว แอปจะกลับมารันเองทุกครั้งที่ VPS reboot ทำให้ระบบของคุณรองรับ uptime ระดับ 99% ได้ตามมาตรฐาน AsiaGB การรวมความสามารถทั้งหมดนี้เข้าด้วยกัน — cluster mode เพื่อกระจายโหลด, การหมุน log เพื่อกันดิสก์เต็ม, และ reload แบบไม่มี downtime เพื่ออัปเดตโค้ดอย่างปลอดภัย — คือสิ่งที่ทำให้ Node.js แอปของคุณพร้อมรับงานจริงในระยะยาว ไม่ใช่แค่รันได้ตอน demo เท่านั้น เมื่อวางรากฐานนี้ครบแล้ว คุณสามารถต่อยอดด้วยการตั้ง backup, แยก database ออกไปอีกเครื่อง หรือเพิ่ม CDN หน้าเว็บได้ตามการเติบโตของแอปอย่างมั่นใจ

Tip: ตั้ง health check endpoint เช่น /healthz ในแอปแล้วให้ Uptime Kuma หรือ monitoring ภายนอก ping ดูทุกนาที จะรู้ทันทีเมื่อแอปมีปัญหา ก่อนที่ผู้ใช้จะแจ้งเข้ามา

คำถามที่พบบ่อย (FAQ)

PM2 ต่างจาก systemd อย่างไร ต้องใช้ตัวไหน?

systemd เป็น init system ของ Ubuntu ที่จัดการ service ระดับ OS ส่วน PM2 เป็น process manager เฉพาะทางสำหรับ Node.js ที่ให้ cluster mode, log management และ zero-downtime reload มาในตัว ในทางปฏิบัติเรามักใช้ทั้งคู่ร่วมกัน คือให้ pm2 startup สร้าง systemd unit ให้ PM2 เริ่มทำงานตอน boot แล้ว PM2 ดูแล Node.js process อีกที

ต้องใช้ VPS RAM เท่าไหร่ถึงจะรัน Node.js + PM2 ได้สบาย?

แอป Express ขนาดเล็กรันได้บน VPS 512 MB แต่หากเปิด cluster mode หลาย worker หรือมี traffic สูง แนะนำ RAM 1 GB ขึ้นไป AsiaGB VPS Linux เริ่มต้น 500 บาท/เดือน บน Ubuntu พร้อม full root access สามารถอัปเกรด RAM/CPU ได้เมื่อแอปโตขึ้น

ทำไมแอปรันได้ตอนพิมพ์ node app.js แต่ขึ้น 502 Bad Gateway ผ่าน Nginx?

มักเกิดจาก 2 สาเหตุ: (1) PM2 ไม่ได้รันแอปอยู่จริง ตรวจด้วย pm2 status ว่า status เป็น online หรือไม่ และ (2) port ใน proxy_pass ของ Nginx ไม่ตรงกับ port ที่แอปฟัง ตรวจว่าทั้งสองฝั่งเป็น 3000 ตรงกัน แล้วรัน nginx -t และ systemctl reload nginx

อัปเดตโค้ดใหม่แล้ว PM2 ยังรันโค้ดเก่าอยู่ ทำอย่างไร?

PM2 ไม่ได้โหลดไฟล์ใหม่อัตโนมัติหลัง git pull ต้องสั่ง pm2 reload myapp (cluster mode) หรือ pm2 restart myapp เพื่อโหลดโค้ดใหม่ หากเปลี่ยนค่าใน ecosystem.config.js ให้ใช้ pm2 reload ecosystem.config.js --update-env เพื่อให้ environment variable ใหม่มีผล

สรุป

ต้องการ VPS สำหรับ Node.js?

AsiaGB VPS Linux เริ่มต้น 500 บาท/เดือน · Full Root Access · SSD · Unlimited Bandwidth · เลือก Ubuntu ได้ทุก version

ดูแพ็กเกจ VPS

ดูแพ็กเกจ VPS ไทย ราคาถูกทั้งหมด →