Deploy Nextjs Application on AWS EC2(ubuntu) Via PM2 and Reverse proxy with Nginx
ใช้ pm2 รัน Nextjs Application บน AWS EC2 และทำ Reverse proxy ด้วย Nginx
*จริงๆแล้ว server ที่เราเลือกใช้ไม่ว่าจะเจ้าไหนก็จะไม่ต่างกันมาก เพราะหลักๆ คือเราใช้ Linux ubuntu เป็น OS image หลัก แต่ในบทความนี้จะใช้ AWS EC2 ครับ
Components
- Nextjs project
- AWS EC2
- PM2
- Domain name
- Cloudflare
- Nginx
เตรียมตัว
- เตรียม source code ของโปรเจคให้เรียบร้อย และ push ขึ้น Github
- Launch AWS EC2 instance
- config security group ของ EC2 instance (เพื่อให้สามารถเข้าถึง port ได้)
- port22 สำหรับ SSH เข้าไปยัง EC2 instance
- 3000 สำหรับ port ของ Application
- 80 สำหรับ HTTP
- 443 สำหรับ HTTPS
ลุยยย…
- SSH เข้าไปที่ EC2 instance และ set up
//access to EC2 instance
$ ssh {username}@{IPv4} and password OR use keypair
//set up
$ sudo apt-get update
2. Install nvm
เนื่องจาก application ที่เราจะรัน base on Nodejs แต่จะไม่ลง node ตรงๆ เพราะจะยากต่ออนาคต ถ้าต้องการเปลี่ยน version ของ Nodejs. โดยจะใช้เป็นตัว nvm แทน
$ sudo apt install curl
$ curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
$ source ~/.bashrc
$ nvm install node
//check nvm and node
$ nvm list
3. Clone project จาก Github (บทความนี้จะใช้ fortue-app) และลองรัน app
//clone project
$ git clone https://github.com/{username}/{reponame}.git
//change directory to project
$ cd {project_path}
//install package
$ npm install
//run Nextjs applicatopn
$ npm run dev
เข้าดู application ผ่าน browser ด้วย {IPv4 ของ instance}: 3000
โอเคร application ทำงานได้ดี ✨
❗️❓… แต่ ถ้าเราปิด terminal หรือ exit ออกจาก server ก็จะทำให้ application down ลงไปด้วย เพราะเราไม่ได้รัน application ใน background
💡แก้ด้วย …ซึ่งถ้าเราต้องการทำให้ application ของเราสามารถรันใน backgrond ทำได้ด้วย “PM2”
PM2
ลง pm2 ผ่าน npm
$ npm install pm2 -g
ขั้นตอนการ run application ด้วย PM2
- Build ตัว project
// change directory to target project
$ cd {project_path}
$ npm run build
2. Run application via pm2
$ pm2 start npm --name {project_name} -- start
//case if you want to specific port
$ pm2 start npm --name {project_name} -- start -- -p {port_number}
ดูผลลัพธ์ที่ => {IPv4}:3000
More pm2 cli
//start application
$ pm2 start {name or id}
//stop application
$ pm2 stop {name or id}
//check status
$ pm2 ls
//delete application
$ pm2 delete {name or id}
//check log
$ pm2 monit
ซึ่งจะเห็นว่า application ทำงานได้ปกติ โดย pm2 จะเป็นตัวรันให้ใน background✨
❗️❓… แต่จะเห็นว่า url ของ application ของเรายังใช้ ipv4 ของ instance , port ของ application และยังไม่ secure ด้วย ซึ่งยากในการใช้งานจริง ต่างจากเว็บทั่วไปที่ต่างจาก url ที่เราใช้กันบ่อยๆ ซึ่งจะเป็นชื่อที่เราอ่านออก และมี รูปกุญแจล็อค
💡 ชื่อของ url นั่นคือ Domain name และ กุญแจล็อคนั่นคือการบอกว่า secure connection (SSL)
โดย Domain name ที่เช่ามา ผมจะ register ไปที่ cloud flare และจะใช้ Certificate ที่ Cloudflare generate ให้ เพื่อทำ secure connection ให้กับ application
* ในบทความนี้ไม่ได้พูดถึงการเช่า domain name นะครับ 🙏
Cloudflare
โดย application นี้ผมจะให้มี sub domain name ว่า fortune-day.0xnutx.space
Domain name > DNS
ปรับโหมด SSL ของ CloudFlare
Domain name > SSL/TSL > Overview
สร้าง Certificate จาก CloudFlare
Domain name > SSL/TSL > Origin server > Create certificate
cloudflare จะให้ secret มา 2 ส่วนคือ certificate และ private key เก็บไว้ในที่ที่ปลอดภัย
Nginx
ใช้ Nginx ในการทำ reverse proxy ของตัว port, set domain และทำ SSL ด้วย certitifacte จาก cloudflare
//install
$ sudo apt install nginx-core
//check nginx status
$ sudo systemctl status nginx
โดย Nginx จะอยู่ที่ /etc/nginx
ก็ cd /etc/nginx และเข้าไปที่ folder con.f และทำการสร้างไฟล์ในการ config ชื่อ default.conf
เริ่ม Config ตัว domain name ที่จะให้กับ application ของเรา และทุกครั้งที่เข้า domain นั้น จะให้ forward ไปที่ 443 หรือ HTTPS (SSL) และที่ 443 ทำ reverse proxy ไปที่ port ของ fortune application และมีการดึง certificate และ private key จากที่เรา generate ที่ cloudFlare.
cd /etc/nginx/cond.f
sudo vi default.conf
- สร้างไฟล์ config ของ nginx => “default.conf”
- DNS_name จะเป็นที่ subdomain ที่เราตั้งไว้ก่อนหน้า คือ “fortune-day.0xnutx.space”
- port จะเป็น 3000 ซึ่งจะตรงกับที่ application ที่ pm2 กำลังรันอยู่
//default.conf
server {
listen 80;
server_name {{DNS_name}};
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name {{DNS_name}};
ssl_certificate /etc/nginx/certs/certificate.crt;
ssl_certificate_key /etc/nginx/certs/private.key;
location / {
proxy_pass http://{{private_ip}}:{port};
proxy_set_header Host $host;
}
}
2. สร้าง directory certs เพื่อเก็บ certificate และ private key (ค่าได้จาก certificate และ private key จาก Cloudflare ที่ได้สร้าง และบันทึกไว้ก่อนหน้านี้)
เมื่อ config ตัวไฟล์ default.conf เสร็จแล้วให้ reload ตัว nginx
$ sudo systemctl reload nginx
more nginx cli
//check nginx status
$ sudo systemctl status nginx
//start nginx
$ sudo systemctl start nginx
//stop nginx
$ sudo systemctl stop nginx
//reload nginx / restart
$ sudo systemctl reload nginx
มาดูผลลัพธ์
สำเร็จ fortune app ของเรารันและเข้าถึงได้ตามปกติ เช่นเดียวกับเข้าด้วย ipv4 และ port ของ instance ✨
สรุป
เราได้ deploy Nextjs application ลงบน ubuntu instance server (บทความนี้ใช้ AWS EC2) เริ่มด้วยเรา clone ตัว source code ที่อยู่บน github ลงมาใน server, ติดตั้ง dependencies ที่ต้องการ (node และ npm) จากนั้นทำการ build application และให้ pm2 เป็นคนรัน application ให้เรา. ต่อด้วยการ config reverse proxy เพื่อให้สามารถเข้าถึง application ของเราได้ด้วย Domain
*จริงๆแล้วใน server หนึ่วตัว เราสามารถรัน application และเซ็ท reverse proxy ได้หลายตัวนะ แต่ก็ขึ้นอยู่กับทรัพยากรที่ server เรามีด้วย
*อย่าลืมลบ instance กันด้วย
EC2 > instance > instance state > terminate