วิธี Deploy Node.js app ด้วย pm2 + nginx + ssl บน Ubuntu 18.04

โดยปกติแล้วในการทำ web application ด้วยไม่ว่าจะด้วยภาษาอะไรก็จำเป็นต้องให้ผู้ใช้เราใช้โปรแกรมเราผ่าน web browser ซึ่งถ้าเราทำเป็น public web จำเป็นต้องใช้ผ่าน 2 port หลักๆ คือ 80 http, 443 https ซึ่งโดยปกติแล้วเราจะมักเขียนโปรแกรมภาษา node.js มักจะไม่ได้ให้ผู้ใช้เข้าผ่าน port 80 หรือ 443 ตรงๆ ดังนั้นเราจึงต้องทำ reverse proxy เพื่อเรียกใช้งาน application ผ่าน http protocal ได้ตามปกติซึ่งในที่นี่ขอแนะนำ Nginx โดยเราจะ Deploy บน Ubuntu 18.04 กันครับ

คำสั่งสำหรับติดตั้ง nginx บน server

sudo apt-get update
sudo apt-get install nginx

start application ด้วย pm2 สามารถเข้าไปดูวิธีการติดตั้งและใช้งาน pm2 ได้จาก link นี้นะครับ

ทำ ssl ด้วย let’s encrypt โดยเริ่มต้นติดตั้งเข้าไปที่ server เราก่อนด้วยคำสั่ง

sudo apt-get install letsencrypt

หลังจากติดตั้งเสร็จแล้วเราก็สามารถที่จะสร้าง SSL Certificate ของเราด้วยคำสั่งดังนี้

letsencrypt certonly --standalone -d example.com //example.com

ระบบจะไปสร้าง cert ไว้ที่ folder /etc/letsencrypt/live/example.com ต่อมาเราก็ทำการ config nginx ให้สามารถเข้ามาใช้ web application เราผ่าน http, https ได้โดยมีขั้นตอนดังนี้

cd /etc/nginx/sites-available
cp default example.com
nano example.com

ใส่ค่า config ให้ชี้ไปที่ port ที่เราเปิดไว้เช่น node รับ listener ไว้ที่ 9090 เราก็สามารถตั้งค่าดังตัวอย่าง

upstream socket_nodes {
    ip_hash;
    server localhost:9090 weight=5;
}

ตามด้วย ตั้งค่า virtual host

server_name example.com;

จากนั้นก็มาตั้งค่าในส่วนของการทำ reverse proxy

location / {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://socket_nodes;
}

และตั้งค่า ssl กันต่อครับ

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

**ตัวอย่าง file example.com

upstream socket_nodes {
    ip_hash;
    server localhost:9090 weight=5;
}
server {
      index index.html index.htm;
      server_name example.com;
      location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://socket_nodes;
      }
}
server {
        listen 443;
        server_name app.pnpsw.com;
        index index.html index.htm;
        ssl on;
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        ssl_session_timeout 5m;
        ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;
        location / {
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_http_version 1.1;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $host;
                proxy_pass http://socket_nodes;
        }
}

เมื่อเสร็จขั้นตอนข้างต้นแล้ว เราต้องทำให้ nginx รู้จัก config ของเราด้วยคำสั่ง

sudo ln -s /etc/nginx/sites-available/example.com .

restart nginx กันครับ

sudo service nginx restart

เมื่อเราทำการตั้งค่าทุกอย่างเสร็จเรียบร้อยแล้ว เราก็สามารถเข้าใช้งาน application เราผ่าน url ได้ดังนี้

http://example.com/
https://example.com/

เนื่องด้วย let’s encrypt นั้นมีอายุแค่ 90 วัน ฉนั้นทุกๆ 90 วันเราจำเป็นต้องมาทำการ renew ใหม่ทุกครั้งด้วยคำสั่ง

letsencrypt renew

แนะนำว่าให้ตั้ง crontab ให้ทำการ renew ให้เราทุกๆ 90 วันนะครับเพื่อความสบายใจในการใช้งานนะครับ

crontab -e

@weekly /usr/local/sbin/letsencrypt-renew

Leave a Reply

iameveme