[Next.js] Deploy Next.js ไปยัง Github Pages ด้วย Github Actions
Automate your workflow from idea to production
ประโยคข้างบนผมหยิบยกมาจาก official docs ของ Git Actions เอาจริงค่อนข้างเห็นด้วยมากๆ นะครับ ทุกวันนี้เวลาผมจะทำงาน CI/CD สิ่งแรกที่จะนึกถึงเลยคือ GitHub Actions เพราะมันค่อนข้างครบ จบ ในตัวเดียว(สำหรับงานง่ายๆ) 🥸 🥸 🥸
ถ้าพูดถึงการ Host โปรเจค Next.js คนส่วนใหญ่มักนึกถึง vercel แต่วันนี้เรามาลองใช้ Github Pages และประโยชน์จาก Git Actions ทำ CI/CD กันครับ
มาเริ่มกัน เถอะครับ 😝
สร้างโปรเจค (ถ้ามีแล้ว ข้ามขั้นตอนนี้ได้เลย)
- ทำการสร้างโปรเจค Next.js ด้วยคำสั่ง
npx create-next-app my-project
# หรือ
yarn create my-project
- ทำการเปิดเข้าไปในโปรเจคที่ถูกสร้าง
cd my-project && code .
- แก้ไขไฟล์
.gitignore
gh-pages
gh-pages.pub
- แก้ไขไฟล์
package.json
เพิ่มคำสั่ง"export": "next export"
- จากนั้นก็ commit และ push ขึ้นไปไว้ที่ Github โลด!
สร้าง Deploy Key
เพื่อให้ Github Actions สามารถทำการ commit และ push โค๊ดไปยังgh-pages
branch ได้ เราจำเป็นต้องทำการ authentication ก่อน ซึ่งเราจำเป็นจะต้องใช้ Keys สองตัวได้แก่ Public key และ Private key
- สั่งสร้าง keys (ในขั้นตอนนี้ผมให้ดึงค่าที่เราเคยทำ global config ตัว GitHub มาใช้สร้าง key : email)
ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
- Public key —
gh-pages.pub
- Private key —
gh-pages
ตั้งค่า Deploy Key บน Github
เพิ่ม Public Key (Deploy Keys)
- เข้าไปที่ repository ของเรา Settings → Deploy Keys → Add
- Title:
ACTIONS_DEPLOY_KEY
- Key: copy ข้อมูลจากในไฟล์
gh-pages.pub
หรือใช้คำสั่ง
pbcopy < gh-pages.pub
- อย่าลืมกด ✅ ติ๊กถูกตรง Allow write access
- จากนั้นกด Add key โลด
เพิ่ม Private Key (Secrets)
- เข้าไปที่ repository ของเรา Settings → Secrets → Add
- Name:
ACTIONS_SECRET_KEY
- Value: copy ข้อมูลจากในไฟล์
gh-pages
หรือใช้คำสั่ง
pbcopy < gh-pages
- จากนั้นกด Add secretโลด
Github Actions
Bypass Jekyll
ก่อนที่เราจะทำการเขียน workflow เราจะต้องทำการ Bypass Github Pages ไม่ให้มันทำการสร้างไฟล์สำหรับ Jekyll (Bypassing Jekyll on GitHub Pages) โดยเราจะสร้างไฟล์ .nojekyll
ไว้ภายใต้โฟลเดอร์/public
ดังรูป
Config Nextjs
สร้งไฟล์ next.config.js
และเพิ่มคำสั่งนี้เข้าไปในไฟล์ดังกล่าว เพื่อให้ Next.js รู้ว่าไฟล์ Static Assets ของเราถูก Host ไว้ที่ไหน
const isProd = process.env.NODE_ENV === 'production';module.exports = {
reactStrictMode: true,
assetPrefix: isProd ? '/ใส่ชื่อ-github-repo/' : '',};
เขียน WorkFlows
- สร้างโฟลเดอร์
.github
- และสร้างโฟลเดอร์
workflows
ภายใต้โฟลเดอร์.github
อีกที จะได้ตามรูปนี้ครับ
- สร้างไฟล์
deploy.yml
ภายใต้โฟลเดอร์workflows
ตามรูป
- และทำการ copy คำสั่งด้านล่างไปใส่ในไฟล์ deploy.yml
name: Deploy to Github Pages
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deployment:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: NPM install
run: npm install - name: Build
run: |
npm run build
npm run export
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ACTIONS_SECRET_KEY }}
publish_dir: ./out
หรือใครใช้ yarn
name: Deploy to Github Pages
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deployment:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Yarn install
run: yarn install
- name: Build
run: |
yarn run build
yarn run export - name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ACTIONS_SECRET_KEY }}
publish_dir: ./out
- ทำการ push confings ไฟล์ทั้งหมด ขึ้นไปยัง Github
หลังจากนั้น ทุกครั้งที่เราทำการ push code ขึ้นไปบน repo ตัว Github Actions ของเราจะทำการ Build และ Deploy เว็บ Next.js ให้เราอัตโนมัติ ตามรูปครับ 🥳 🥳 🥳
- หลังจากรันไปสักพักจะเจอ
errors
นี้เกิดขึ้น 😂 😂 😂
- วิธีแก้ ทำการเปิดไฟล์
index.js
แล้วเปลี่ยนจากใช้ Image ที่ import มาจาก Next.js มาใช้เป็นแท็ก<img>
แทน และทำการcommit
code ขึ้นไปใหม่
- หลังจากนั้นลองเข้าไปดูเว็บของเราได้ที่ https://your-username.github.io/your-repo-name/
Know Issue:
- หลังจากเปิดดูเว็บ ถ้าสังเกตดีๆ เราจะเห็นว่ารูปของเรานั้นมันโหลดไม่ขึ้น(วางยาอีกแล้ว 😂 😂 😂)
- Workaround: ทำการระบุ
prefix
สำหรับassets
โดยการเปิดไฟล์index.js
และแก้ไขโค๊ดตามรูปด้านล่าง
*** const assetPrefix = '/your-repo-name';
commit
และpush
code ขึ้น Github รอจนbuild
เสร็จและ เข้าไปดูเว็บไซต์ของเรา รูปภาพขึ้นเรียบร้อย เป็นอันเสร็จฮะ 🥳 🥳 🥳
อ่านเพิ่มเติม