Deploy Next.js with GitHub, AWS CodePipeline, CodeBuild, CodeDeploy, EC2, S3

之前一直想要把CI/CD跟Cloud Platform學起來,剛好在幾周前上完AWS的考證班(最初我以為課程有實作,誤會大了,等我實做過一陣子再去考那些證吧),而講師把整個AWS的常用功能,透過比對地端跟雲端相似(異)的地方,以及把實戰上應用場景全部過了一遍,也帶到很多相關經驗,讓我對於雲平台整體解決的問題有了一定的了解,所以打鐵趁熱花了幾天把想串CI/CD的心願直接在AWS上做個實踐。

雖然說CI/CD這件事最難的還是在於測試該怎麼寫,怎麼讓大家會寫,而且寫得快又正確,CI/CD工具的使用應該佔不到百分之一的困難,不過本篇就先講簡單的。

優點及缺點

挑選AWS的CI/CD體系總的來說有一個優點跟一個缺點:

缺點:要付的錢可能看起來稍微多一些些,但要想想時間就是金錢

優點:都在AWS平台上,功能大致會遵循著相同平台的邏輯。某種程度上這些雲端廠商為了競爭客戶,會把功能做到點點按按就可以完成,而且文件應該算是完整,以導入的初期來說,省下時間人力去研究好幾套邏輯不一樣工具的時間(gitlab, jenkins, ansible, puppet等),而且還不用去喬實體機器資源,不用維護實體機器,或許就可以COVER掉前面所說的缺點吧!熟悉了CI/CD build,deploy的邏輯後,有需要再去研究其他工具也不遲。

CodePipeline的整體邏輯

建置CodePipeline過程中遇到的問題

這pipeline上顯示的樣子,如果這邊有fail,在紅框內的Details,點進去看錯誤訊息跟google一下就大概有辦法解決。

Policy

跟使用其他AWS的服務一樣,一開始要有IAM, Policy, Role等觀念,因為各個服務之間的串接會需要讓Role帶有對應的Permission,譬如說CodeDeploy要存取S3, EC2,就要建立一個掛有存取S3, EC2 Permission的CodeDeployRole。

Build

version: 0.2
phases:
  install:
    commands:
      - echo Installing dependency...
      - npm install
  build:
    commands:
      - echo Build started on `date`
      - npm run build
  post_build:
    commands:
      - echo Build completed on `date`
artifacts:
  files:
    - .next/**/*
    - package.json
    - next.config.js
    - next-i18next.config.js
    - tsconfig.json
    - tsconfig.server.json
    - appspec.yml
    - deploy_scripts/*

Deploy

Deploy過程中如果遇到問題,記得到EC2 Instance裡面找到log file去看問題,https://docs.aws.amazon.com/codedeploy/latest/userguide/deployments-view-logs.html,這份文件裡面有說路徑在哪,通常有這份log就足夠看出問題點了。

只是這次用Next.js最大問題其實都卡在對於linux檔案權限設定的問題,我查了半天好像跟npm能處理的權限有關,這邊可以看到777指令都出來了,需要對檔案進行權限的開放,這一段應該不算AWS的鍋,只是在linux跟AWS都不熟的情況下會分不清楚是什麼狀況。

version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/my-app
file_exists_behavior: OVERWRITE
permissions:
  - object: /home/ec2-user/my-app
    owner: ec2-user
    mode: 777
hooks:
  ApplicationStop:
    - location: deploy_scripts/step1_application_stop.sh
      timeout: 300
      runas: ec2-user
  BeforeInstall:
    - location: deploy_scripts/step2_before_install.sh
      timeout: 300
      runas: ec2-user
  AfterInstall:
    - location: deploy_scripts/step3_after_install.sh
      timeout: 300
      runas: ec2-user
  ApplicationStart:
    - location: deploy_scripts/step4_application_start.sh
      timeout: 300
      runas: ec2-user
  ValidateService:
    - location: deploy_scripts/step5_validate_server.sh
      timeout: 300
      runas: ec2-user
# === step1_application_stop.sh ===

#!/bin/bash
pkill node

# === step2_before_install.sh ===

#!/bin/bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
. ~/.nvm/nvm.sh
nvm install 16.13.0
DIR="/home/ec2-user/my-app"
if [ -d "$DIR" ]; then
  echo "${DIR} exists"
else
  echo "Creating ${DIR} directory"
  mkdir ${DIR}
fi

# === step3_after_install.sh 沒做事 ===

# === step4_application_start.sh ===

#!/bin/bash
echo "start server"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # loads nvm bash_completion (node is in path now)

sudo chmod -R 777 /home/ec2-user/my-app

cd /home/ec2-user/my-app

npm install
#npm run build
npm run start > /dev/null 2> /dev/null < /dev/null &

# === step5_validate_server.sh 沒做事 ===

總結

好了,這邊只是個速記,過程中有發現AWS更新其實很快,現在介面好像比以前好看許多。

使用它的好處真的是邏輯一致串接快速,付費的部分嘛~目前我還在免費試用期,到時候再看看,聽說現在GCP在搶市占比較便宜啦XD

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *