Next.js 專案使用 GitLab CI/CD 到 GCP (GKE) 教學
__Notes
Next.jsGitLabCI/CDGCPDockerKubernetesDevOps
前言
在現代網頁開發中,自動化部署(CI/CD)已經成為標準實踐。本文將帶領您一步步將 Next.js 專案透過 GitLab CI/CD 部署到 Google Kubernetes Engine (GKE),適合完全沒接觸過的新手跟著實作。
環境準備
在開始之前,請確保您已經準備好以下項目:
-
開發環境
- Node.js (建議 18.x 以上)
- Git
- Docker Desktop
- Google Cloud SDK
-
帳號設定
- GitLab 帳號(需要有容器倉庫權限)
- Google Cloud Platform 帳號
步驟一:Next.js 專案準備
首先,確保您的 Next.js 專案能夠正常運作:
bash
# 建立新的 Next.js 專案
pnpm create next-app --typescript
cd next-app
# 安裝必要依賴
pnpm install
# 測試運行
pnpm dev
步驟二:Docker 容器化
1. 建立 Dockerfile
在專案根目錄創建 Dockerfile:
Dockerfile
dockerfile
# 建置階段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN pnpm install
COPY . .
RUN pnpm build
# 執行階段
FROM node:18-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]
2. 更新 next.config.ts
next.config.ts
typescript
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone',
// 其他配置...
};
module.exports = nextConfig;
步驟三:設定 GitLab CI/CD
1. 設定 GitLab Container Registry
-
確認專案的 Container Registry 功能已啟用:
- 進入專案設定 -> Packages & Registries -> Container Registry
- 確認狀態為啟用
-
取得 Container Registry 路徑(兩者其一):
- registry.gitlab.com/username/project-name
- registry.gitlab.com/group/project-name
2. 建立 .gitlab-ci.yml
在專案根目錄創建 .gitlab-ci.yml:
.gitlab-ci.yml
yaml
image: docker:latest
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ''
DOCKER_HOST: tcp://docker:2375
# 使用 GitLab Container Registry
REGISTRY_IMAGE: $CI_REGISTRY_IMAGE
stages:
- build
- test
- deploy
# 使用 GitLab 內建的 registry 認證
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build:
stage: build
script:
- docker build -t $REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $REGISTRY_IMAGE:$CI_COMMIT_SHA
# 如果是主分支,也標記為最新版本
- |
if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
docker tag $REGISTRY_IMAGE:$CI_COMMIT_SHA $REGISTRY_IMAGE:latest
docker push $REGISTRY_IMAGE:latest
fi
test:
stage: test
script:
- docker pull $REGISTRY_IMAGE:$CI_COMMIT_SHA
- docker run $REGISTRY_IMAGE:$CI_COMMIT_SHA npm test
deploy:
stage: deploy
image: google/cloud-sdk
script:
- echo $GCP_SERVICE_KEY > gcloud-service-key.json
- gcloud auth activate-service-account --key-file gcloud-service-key.json
- gcloud config set project $GCP_PROJECT_ID
- gcloud config set compute/zone $GCP_COMPUTE_ZONE
- gcloud container clusters get-credentials $GCP_CLUSTER_NAME
# 使用 GitLab Container Registry 的映像
- kubectl set image deployment/$KUBE_DEPLOYMENT_NAME $KUBE_CONTAINER_NAME=$REGISTRY_IMAGE:$CI_COMMIT_SHA
only:
- main
3. 設定 GitLab CI/CD 變數
在 GitLab 專案設定中,添加以下環境變數:
GCP_SERVICE_KEY
: GCP 服務帳號金鑰(JSON 格式)GCP_PROJECT_ID
: GCP 專案 IDGCP_COMPUTE_ZONE
: GCP 計算區域GCP_CLUSTER_NAME
: GKE 叢集名稱KUBE_DEPLOYMENT_NAME
: Kubernetes 部署名稱KUBE_CONTAINER_NAME
: Kubernetes 容器名稱
注意:不需要設定 Docker Hub 相關的變數,因為我們使用 GitLab 內建的 Container Registry。
4. 更新 Kubernetes 配置
更新 kubernetes/deployment.yaml 中的映像路徑:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextjs-app
spec:
replicas: 3
selector:
matchLabels:
app: nextjs-app
template:
metadata:
labels:
app: nextjs-app
spec:
containers:
- name: nextjs-app
# 使用 GitLab Container Registry 的映像
image: registry.gitlab.com/your-group/your-project:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
imagePullSecrets:
- name: gitlab-registry
5. 設定 Kubernetes 存取 GitLab Container Registry
- 創建 Registry 認證密鑰:
bash
kubectl create secret docker-registry gitlab-registry \
--docker-server=registry.gitlab.com \
--docker-username=<your-gitlab-username> \
--docker-password=<your-gitlab-access-token> \
--docker-email=<your-email>
步驟四:設定 GCP 和 GKE
1. 建立 GCP 專案
- 登入 Google Cloud Console
- 建立新專案
- 啟用必要的 API:
- Kubernetes Engine API
- Container Registry API
2. 建立 GKE 叢集
bash
# 設定專案
gcloud config set project YOUR_PROJECT_ID
# 建立 GKE 叢集
gcloud container clusters create my-cluster \
--zone asia-east1-a \
--num-nodes 3 \
--machine-type e2-medium
3. 建立 Kubernetes 配置
建立 kubernetes/deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextjs-app
spec:
replicas: 3
selector:
matchLabels:
app: nextjs-app
template:
metadata:
labels:
app: nextjs-app
spec:
containers:
- name: nextjs-app
image: registry.gitlab.com/your-group/your-project:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
imagePullSecrets:
- name: gitlab-registry
步驟五:部署流程
- 提交程式碼到 GitLab
bash
git add .
git commit -m "Initial deployment setup"
git push origin main
- 監控部署過程
- 在 GitLab CI/CD Pipeline 頁面查看部署狀態
- 使用 kubectl 命令檢查部署狀態:
bash
kubectl get pods
kubectl get services
- 驗證部署
- 使用 kubectl get service nextjs-app-service 獲取外部 IP
- 在瀏覽器訪問該 IP 確認應用是否正常運行
常見問題與解決方案
1. Docker 建置失敗
- 檢查 Dockerfile 語法
- 確認 Docker Hub 憑證正確
- 檢查網路連接狀況
2. GitLab CI/CD 失敗
- 確認環境變數設定正確
- 檢查 .gitlab-ci.yml 語法
- 查看 Pipeline 日誌了解詳細錯誤
3. GKE 部署問題
- 確認 GCP 憑證正確
- 檢查 GKE 叢集狀態
- 確認 Kubernetes 配置文件正確
最佳實踐建議
-
安全性考量
- 使用環境變數存儲敏感資訊
- 定期更新 Docker 映像
- 實施適當的存取控制
-
效能優化
- 使用多階段 Docker 建置
- 實施快取機制
- 適當設定資源限制
-
監控與維護
- 設置監控告警
- 實施日誌收集
- 定期更新依賴套件
-
Container Registry 最佳實踐
- 定期清理舊的容器映像
- 使用具體的標籤而不是 latest
- 實施映像掃描檢查安全漏洞
- 設定適當的存取權限控制