รับเครดิต $200

Deploy แอป Node.js บน DigitalOcean ด้วย PM2 + Nginx + SSL ฟรี (Let's Encrypt) ทีละขั้น

อัปเดตล่าสุด 3 พฤศจิกายน 2569 · อ่านประมาณ 7 นาที · โดย DigitalOcean Review ไทย

สอน deploy แอป Node.js (Express/Next.js/NestJS) บน Droplet Ubuntu ด้วย Node ผ่าน nvm, PM2 ให้รันต่อเนื่องและรีสตาร์ตอัตโนมัติ, Nginx reverse proxy และ SSL ฟรีจาก Let's Encrypt พร้อมสคริปต์อัปเดตโค้ด

เปิดเผยข้อมูล: บทความนี้มีลิงก์แนะนำ (referral) ของ DigitalOcean หากคุณสมัครผ่านลิงก์ เจ้าของเว็บอาจได้รับเครดิต โดยคุณไม่เสียค่าใช้จ่ายเพิ่ม · อ่านนโยบายการรีวิว

ภาพรวมสถาปัตยกรรม

เมื่อ deploy แอป Node.js บน Droplet โครงสร้างมาตรฐานคือ

  1. แอป Node.js ฟังพอร์ตภายใน เช่น 3000 (ไม่เปิดสู่สาธารณะโดยตรง)
  2. PM2 เป็น process manager ที่ดูแลให้แอปรันตลอด รีสตาร์ตเมื่อพัง และเปิดเองเมื่อเครื่องรีบูต
  3. Nginx รับคำขอพอร์ต 80/443 จัดการ SSL แล้วส่งต่อ (reverse proxy) ไปยังแอป
  4. Certbot ขอและต่ออายุใบรับรอง Let's Encrypt อัตโนมัติ

ถ้าไม่อยากดูแลเซิร์ฟเวอร์เอง คู่มือ App Platform deploy จาก Git ให้อัตโนมัติ แต่แบบ Droplet ควบคุมได้เต็มที่และคุมต้นทุนได้ดีเมื่อมีหลายแอปบนเครื่องเดียว

ก่อนเริ่ม

รับเครดิตฟรี $200 (ใช้ได้ 60 วัน)สมัคร DigitalOcean ผ่านลิงก์แนะนำของเรา แล้วเพิ่มวิธีชำระเงินที่ใช้งานได้ ระบบจะให้เครดิตทดลองใช้งาน ตามเงื่อนไขของ DigitalOcean ณ วันที่สมัคร
สมัครรับเครดิต $200 →

ขั้นที่ 1: ติดตั้ง Node.js ด้วย nvm

nvm ช่วยสลับเวอร์ชัน Node ต่อผู้ใช้โดยไม่ต้องใช้ sudo

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
source ~/.bashrc
nvm install --lts
node -v
npm -v

ตรวจคำสั่งติดตั้งล่าสุดและเลขเวอร์ชันของสคริปต์ nvm ที่หน้า GitHub ของโปรเจกต์ nvm ก่อนรัน ทุกครั้งที่ pipe สคริปต์เข้า bash

ขั้นที่ 2: นำโค้ดขึ้นเครื่อง

sudo apt install -y git
cd ~
git clone https://github.com/USER/REPO.git app
cd app
npm ci --omit=dev
  • ใช้ npm ci เพื่อให้ได้เวอร์ชัน dependency ตรงกับ lockfile
  • ถ้าเป็น Next.js/TypeScript ให้รัน npm ci && npm run build ก่อน
  • ไฟล์ตั้งค่าลับเก็บใน .env บนเซิร์ฟเวอร์ ห้าม commit ขึ้น Git

ทดสอบรันก่อน: node server.js หรือ npm start แล้วลอง curl http://127.0.0.1:3000 จากเครื่องเดียวกัน

ขั้นที่ 3: รันด้วย PM2

npm install -g pm2
pm2 start server.js --name myapp
pm2 status
pm2 logs myapp

ให้เริ่มอัตโนมัติเมื่อเครื่องรีบูต

pm2 startup systemd

PM2 จะพิมพ์คำสั่ง sudo env PATH=... pm2 startup ... ออกมา ให้คัดลอกไปรันตามที่แสดง แล้วบันทึกรายการแอป

pm2 save

ไฟล์ ecosystem (แนะนำเมื่อมีหลายแอป)

module.exports = {
  apps: [{
    name: 'myapp',
    script: 'server.js',
    instances: 'max',
    exec_mode: 'cluster',
    max_memory_restart: '400M',
    env: { NODE_ENV: 'production', PORT: 3000 }
  }]
}

รันด้วย pm2 start ecosystem.config.js โหมด cluster ใช้ได้ทุก vCPU แต่กินหน่วยความจำเพิ่มตามจำนวน instance บนเครื่อง 1 vCPU ไม่ต้องใช้ cluster

ขั้นที่ 4: ตั้ง Nginx เป็น reverse proxy

sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/myapp

ใส่เนื้อหา

server {
    listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://127.0.0.1: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_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

เปิดใช้และตรวจไวยากรณ์

sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo ufw allow 'Nginx Full'

หัวข้อ Upgrade/Connection จำเป็นถ้าแอปใช้ WebSocket (เช่น Socket.IO) และแอปที่อยู่หลัง proxy ต้องตั้ง trust proxy (Express: app.set('trust proxy', 1)) เพื่ออ่าน IP ผู้ใช้จริง

ขั้นที่ 5: SSL ฟรีด้วย Certbot

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run

Certbot แก้ไฟล์ Nginx ให้อัตโนมัติ เพิ่มการ redirect จาก HTTP ไป HTTPS และตั้งตัวต่ออายุอัตโนมัติ คำสั่ง --dry-run ใช้ยืนยันว่าการต่ออายุทำงาน

ถ้า Certbot ล้มเหลว สาเหตุที่พบบ่อยคือ DNS ยังไม่ชี้มาที่ IP นี้ หรือพอร์ต 80 ถูกไฟร์วอลล์ (UFW หรือ Cloud Firewall) ปิดอยู่

ขั้นที่ 6: สคริปต์อัปเดตโค้ด

สร้าง ~/deploy.sh

#!/bin/bash
set -e
cd ~/app
git pull --ff-only
npm ci --omit=dev
# npm run build   # ถ้ามีขั้น build
pm2 reload myapp

chmod +x ~/deploy.sh แล้วรัน ./deploy.sh ทุกครั้งที่อัปเดต โหมด pm2 reload ในโหมด cluster ทำ zero-downtime ได้ ส่วนโหมดปกติจะรีสตาร์ตสั้นๆ

ความปลอดภัยและความเสถียร

  1. ไม่รันแอปด้วย root ใช้ผู้ใช้ปกติตลอด
  2. เปิดเฉพาะพอร์ต 22/80/443 พอร์ต 3000 ไม่ต้องเปิดสาธารณะ ดู Cloud Firewall และ VPC
  3. จำกัดขนาดคำขอ ใน Nginx ด้วย client_max_body_size
  4. เปิด log rotation ของ PM2: pm2 install pm2-logrotate
  5. ตั้ง alert เมื่อ CPU/RAM/ดิสก์สูง ดู Monitoring และ Alerts
  6. สำรองข้อมูลและฐานข้อมูล ดู Backups และ Snapshots

แก้ปัญหาที่พบบ่อย

อาการสาเหตุที่เป็นไปได้วิธีแก้
502 Bad Gatewayแอปไม่ได้รัน หรือพอร์ตไม่ตรงpm2 status, pm2 logs, ตรวจ proxy_pass
แอปล้มทุกครั้งตอน buildRAM ไม่พอเพิ่ม swap หรืออัปเกรด Droplet
รีบูตแล้วแอปไม่ขึ้นยังไม่ได้ pm2 startup + pm2 saveทำซ้ำสองคำสั่งนี้
WebSocket ขาดตลอดไม่ได้ตั้ง Upgrade headerเพิ่มหัวข้อตามตัวอย่างข้างต้น
Certbot ไม่ผ่านDNS/พอร์ต 80ตรวจ A record และไฟร์วอลล์

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

ใช้ PM2 หรือ Docker ดี

ถ้ามีแอปเดียวหรือไม่กี่แอป PM2 ง่ายและเบา ถ้าต้องการความสม่ำเสมอของสภาพแวดล้อมหรือรันบริการหลายชนิดรวมกัน ดู ติดตั้ง Docker บน Droplet

รันหลายแอปบน Droplet เดียวได้ไหม

ได้ ให้แต่ละแอปฟังพอร์ตต่างกันและสร้าง server block ของ Nginx แยกตามโดเมน ระวัง RAM รวมของทุกแอป

ต้องใช้ Load Balancer ไหม

ยังไม่จำเป็นสำหรับเว็บเล็ก เมื่อทราฟฟิกโตจนต้องใช้หลายเครื่อง ค่อยดู คู่มือ Load Balancer

รับเครดิตฟรี $200 (ใช้ได้ 60 วัน)สมัคร DigitalOcean ผ่านลิงก์แนะนำของเรา แล้วเพิ่มวิธีชำระเงินที่ใช้งานได้ ระบบจะให้เครดิตทดลองใช้งาน ตามเงื่อนไขของ DigitalOcean ณ วันที่สมัคร
สมัครรับเครดิต $200 →