DDevArchive
Đăng nhập

Deploy lên VPS: Nginx, HTTPS và giám sát sơ khởi

Deploy không phải "chạy node trên server". Nó là: chạy sau systemd, chặn trước bằng Nginx, khoá bằng HTTPS, và biết nhìn log khi hỏng. Làm đúng quy trình này bạn sẽ không còn sợ đêm có sự cố.

Chạy ứng dụng như service bằng systemd

Nếu bạn chạy node server.js rồi tắt SSH, server chết theo. systemd quản lý tiến trình: tự khởi động khi boot, restart khi crash, ghi log tập trung.

// File: app.service
[Unit]
Description=MyApp
After=network.target

[Service]
User=deploy
WorkingDirectory=/var/www/my-app
ExecStart=/usr/bin/node src/server.js
Restart=always
RestartSec=3
EnvironmentFile=/etc/my-app.env

[Install]
WantedBy=multi-user.target
// File: terminal.sh
sudo cp app.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now my-app
sudo systemctl status my-app
journalctl -u my-app -f      # xem log theo thời gian thực

Nginx: cổng vào duy nhất

Nginx đứng trước Node: phục vụ file tĩnh, proxy request tới app, xử lý HTTPS, cân tải. Node không nên lộ trực tiếp ra Internet.

// File: nginx.conf
server {
  listen 80;
  server_name app.example.com;

  location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }

  # file tĩnh không cần đụng Node
  location /static/ {
    alias /var/www/my-app/public/;
    expires 7d;
  }
}
Node không phải web server

Nginx xử lý keep-alive, compression, file tĩnh, TLS nhanh hơn Node nhiều. Đừng để Node “gánh” mấy việc đó. Đây cũng là câu hỏi phỏng vấn rất hay gặp.

HTTPS miễn phí bằng Let’s Encrypt

// File: https.sh
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app.example.com

# certbot tự sửa nginx.conf và gia hạn tự động
sudo certbot renew --dry-run

Biến môi trường và bảo mật server

Secret không nằm trong git. Đặt trong /etc/my-app.env với quyền chỉ root đọc, cấm SSH bằng mật khẩu (chỉ dùng key), đổi port SSH, bật firewall chỉ chừa 80/443/22.

❓ Khi bạn tắt terminal SSH, ứng dụng vẫn phải chạy. Giải pháp đúng?

  • Chạy app qua systemd
  • Cấu hình Nginx reverse proxy
  • Gắn HTTPS bằng Let’s Encrypt
  • Đặt secret trong env file, không trong git