การ Deploy โปรเจกต์ React โดยใช้ Amazon S3 และ Amazon CloudFront

บทความนี้ ผมจะมาพูดถึงเกี่ยวกับการใช้ Amazon S3 เพื่อเป็น Static website สำหรับ React และให้ใช้งานเว็บไซต์ผ่าน Amazon CloudFront แทนครับ

ข้อกำหนดเบื้องต้น

  • โปรเจกต์ React ที่พร้อมใช้งาน (หากไม่มีสามารถนำโปรเจกต์ที่จัดเตรียมไว้ให้ตาม ลิงก์ โดยใช้คำสั่ง git clone ได้เลยครับ)
  • EC2 สำหรับโปรเจกต์ React
    สามารถดูวิธีการสร้าง EC2 ได้ที่ลิงก์ด้านล่างนี้
    โดยตอนสร้างแนะนำว่าให้เปลี่ยน instance type เป็น t3a.medium และ Key pair เป็น .pem สำหรับการ SSH โดยใช้ VSCode

  • EC2 ที่ Extention Remote – SSH กับ VSCode
    สามารถดูวิธีการติตตั้ง Extention Remote – SSH ได้ที่ลิงก์ด้านล่างนี้

  • Domain Name System (DNS) ที่มีการจดทะเบียนแล้ว
    สามารถดูวิธีการซื้อ Domain ได้ที่ลิงก์ด้านล่างนี้

Step 1: เตรียมโปรเจกต์ React สำหรับอัปโหลดขึ้น Amazon S3

หลังจากที่เตรียม EC2 เรียบร้อยแล้ว ให้ใช้ VSCode ทำการ Extention Remote – SSH ไปยัง EC2 จากนั้นให้เปิดหน้า Terminal แล้วใช้คำสั่งตามนี้

sudo yum install git

จากนั้นจึงใช้คำสั่ง git clone โปรเจกต์ React มา

git clone https://github.com/patarapongCMTH/Tic-Tac-Toe

ให้เข้าไปที่โฟลเดอร์ที่เก็บโปรเจกต์ React อยู่ ตามด้วยติดตั้ง Node.js ด้วยคำสั่งตามนี้

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

จากนั้นทำการใช้คำสั่งตามนี้เพื่อสร้างโฟลเดอร์ node_modules

npm i
npm start

ในกรณีที่มี โปรเจกต์ React อยู่แล้ว สามารถใช้คำสั่งตามนี้ได้เลย

npx create-react-app my-app
cd my-app
npm start

หลังจากที่ใช้คำสั่ง npm start ให้ใช้คำสั่งนี้ เพื่อสร้างโฟลเดอร์ build

npm run build

จากนั้นจะมีโฟลเดอร์ build ปรากฏขึ้นมาตามรูป

ให้ทำการดาวน์โหลดโฟลเดอร์ build เก็บไว้เพื่อนำไปอัปโหลดขึ้น Amazon S3 ในขั้นตอนถัดไป

รายชื่อไฟล์ที่มีในโฟลเดอร์ build

Step 2: Deploy โปรเจกต์ React ขึ้น Amazon S3

2.1: สร้าง S3 Bucket

เข้ามาที่ AWS management console แล้วเข้าไปที่ Amazon S3 จากนั้นให้คลิก Create bucket
ในส่วนของ Bucket name สามารถตั้งชื่อได้ตามที่ต้องการ ซึ่งในบทความนี้ผมจะใช้ชื่อ patarapong.react

ในส่วนหัวข้อ Block Public Access settings for this bucket ให้ติ๊ก Block all public access ออก และให้ติ๊ก
I acknowledge that the current settings might result in this bucket and the objects within becoming public ไว้
ในส่วนที่เหลือผมจะปล่อยให้เป็นค่า default จากนั้นเลื่อนลงมาด้านล่างสุดและคลิก Create bucket

2.2: Deploy โปรเจกต์ React ไปที่ S3

เข้ามาที่ Bucket ที่เราสร้าง จากนั้นให้คลิกที่ Upload ให้คลิกที่ Add files เพื่ออัปโหลดไฟล์ทั้งหมดในโฟลเดอร์ build และคลิก Add folder เพื่ออัปโหลดโฟลเดอร์ static

หลังจากอัปโหลดเสร็จเรียบร้อย S3 ของเราจะมีไฟล์และโฟลเดอร์ตามรูปด้านล่างนี้

2.3: ตั้งค่า Static website

ใน Bucket ของเรา ให้เข้ามาที่ Properties แล้วเลื่อนลงมาจนถึงหัวข้อ Static website hosting แล้วกด Edit

ทำการตั้งค่าตามรูปด้านล่าง และในช่อง Index document ให้ใส่ index.html แล้วกด Save changes

หลังจากนั้นเราจะได้ URL สำหรับใช้งาน S3 เป็น Static website แต่ยังไม่สามารถใช้งานได้ เราต้องไปตั้งค่าใน Permission ก่อน

ให้เรามาที่ Permission จากนั้นคลิก Edit ตรงหัวข้อ Bucket policy
ให้ใส่ Policy ไปตามด้านล่างนี้ โดยให้เปลี่ยนตรง [Bucket name] ให้เป็นชื่อของ Bucket ที่เราตั้งไว้ แล้วกด Save changes

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[Bucket name]/*"
        }
    ]
}

ทดลองนำ URL ของ S3 ไปใช้งานใน Web browser

เพียงเท่านี้เราก็สามารถใช้งาน โปรเจกต์ React ที่เราพัฒนาผ่าน Amazon S3 ได้แล้วครับ
ต่อไปจะเป็นขั้นตอนการตั้งค่าให้ใช้ Website ผ่านทาง CloudFront และ Route 53 แทนที่จะใช้ URL ของ S3 โดยตรง

Step 3: การใช้งาน Website ผ่าน Amazon CloudFront

สามารถดูขั้นตอนการใช้งานได้ทางบทความด้านล่างนี้ โดยเริ่มจากหัวข้อ การแสดงผลเว็บไซต์ผ่าน Amazon CloudFront
โดยใช้ URL ของ S3 แทน Public IPv4 DNS ของ EC2

Step 4: การใช้งานผ่าน Amazon Route 53 (DNS) และการตั้งค่า ACM (SSL)

สามารถดูได้ที่บทความด้านล่างนี้

Step 5: ปิด public access ของ S3

หลังจากที่เราตั้งค่าให้สามารถใช้งานเว็บไซต์ผ่าน Amazon CloudFront และใช้งาน DNS ผ่าน Amazon Route 53 ได้แล้ว
เราจะมาตั้งค่าให้มีแค่ Amazon CloudFront เท่านั้นที่เข้าถึง Amazon S3 ได้
โดยใน AWS management console ให้ทำการ disable ในส่วนของ Static website hosting จากนั้นให้มาที่หน้า Permission ของ S3 แล้วคลิกที่ Edit หัวข้อ Block public access (bucket settings) ตามภาพ

ติ๊กในช่องที่เขียนว่า Block all public access จากนั้นคลิก Save changes

จะมีข้อความปรากฏขึ้นมาให้เรายืนยัน ให้พิมพ์ข้อความตามที่ระบบต้องการ จากนั้นจึงคลิก Confirm

จากนั้นในหัวข้อ Bucket policy ให้ลบ policy เดิม แล้วเปลี่ยนเป็น policy ตามด้านล่าง โดยเปลี่ยน [Bucket name] เป็นชื่อ Bucket ของเรา และเปลี่ยน [CloudFront ARN] เป็น ARN ของ CloudFront โดยสามารถคัดลอกมาจากหน้า General ของ CloudFront

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipalReadOnly",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::[Bucket name]/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "[CloudFront ARN]"
                }
            }
        }
    ]
}


จากนั้นให้มาที่ Amazon CloudFront ในส่วนของหน้า Origins ให้ทำการติ๊กที่ Origin name ของเรา ตามด้วยคลิกที่ Edit

ในหน้านี้ให้เราทำการแก้ไขตามรูปด้านล่าง โดยในช่อง Origin domain ให้เปลี่ยน [bucket name].s3-website-ap-southeast-1.amazonaws.com (website endpoint) ไปเป็น [bucket name].s3.ap-southeast-1.amazonaws.com (REST API endpoint) และในส่วนของ Origin access control ก็ให้ใช้ REST API endpoint เช่นกัน จากนั้นคลิก Save changes

กลับมาที่ General ของ Amazon CloudFront คลิก Edit ตามภาพ

เลื่อนลงมาด้านล่าง ในส่วนของ Default root object - optional ให้ใส่ index.html จากนั้นคลิก Save changes

หลังจากที่ตั้งค่าเสร็จเรียบร้อย เมื่อนำ URL ของ S3 ไปใช้งาน จะไม่สามารถใช้งานได้ตามภาพด้านล่าง

เมื่อเรานำลิงก์ URL ของ Amazon CloudFront หรือ Amazon Route 53 มาใช้งาน จะเห็นได้ว่ายังสามารถทำงานได้ตามปกติ

สรุป

เราสามารถนำโปรเจกต์ต่างๆมาใช้งานบน Amazon S3 เนื่องจาก Amazon S3 ที่เป็นเหมือนคลังที่เก็บข้อมูลได้ทุกอย่าง สามารถทำเป็น Static website ได้ นอกจากนี้เราสามารถตั้งค่าให้ใช้งานผ่าน Amazon CloudFront และ Amazon Route 53 เพื่อให้เว็บไซต์ของเรามีความปลอดภัยมากยิ่งขึ้น

บทความต้นฉบับ

บทความที่เกี่ยวข้อง