[Next.js] Deploy Next.js ไปยัง Github Pages ด้วย Github Actions

W.Songsak
4 min readSep 20, 2021

--

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 ให้เราอัตโนมัติ ตามรูปครับ 🥳 🥳 🥳

Github Actions กำลัง Build และ Deploy
  • หลังจากรันไปสักพักจะเจอ errors นี้เกิดขึ้น 😂 😂 😂
Error: Image Optimization using Next.js’ default loader is not compatible with `next export`.
  • วิธีแก้ ทำการเปิดไฟล์ index.js แล้วเปลี่ยนจากใช้ Image ที่ import มาจาก Next.js มาใช้เป็นแท็ก <img> แทน และทำการ commit code ขึ้นไปใหม่
index.js
Github Actions ทำการ Deploy Next.js สำเร็จ

Know Issue:

  • หลังจากเปิดดูเว็บ ถ้าสังเกตดีๆ เราจะเห็นว่ารูปของเรานั้นมันโหลดไม่ขึ้น(วางยาอีกแล้ว 😂 😂 😂)
ไฟล์รูปภายใต้ /public/*
  • Workaround: ทำการระบุ prefix สำหรับ assets โดยการเปิดไฟล์ index.js และแก้ไขโค๊ดตามรูปด้านล่าง

*** const assetPrefix = '/your-repo-name';

  • commit และ push code ขึ้น Github รอจน build เสร็จและ เข้าไปดูเว็บไซต์ของเรา รูปภาพขึ้นเรียบร้อย เป็นอันเสร็จฮะ 🥳 🥳 🥳

อ่านเพิ่มเติม

--

--

W.Songsak
W.Songsak

Written by W.Songsak

Software Engineer 👩‍💻 Doing: React, React Native & NextJS also Flutter(Side projects) 💅 Todo: UI/UX

No responses yet