1+ name : Docker Build and Deploy
2+
3+ on :
4+ push :
5+ branches : [ main, master ]
6+ pull_request :
7+ branches : [ main, master ]
8+
9+ env :
10+ REGISTRY : ghcr.io
11+ IMAGE_NAME_FRONTEND : ${{ github.repository }}/kb-frontend
12+ IMAGE_NAME_BACKEND : ${{ github.repository }}/kb-backend
13+
14+ jobs :
15+ build-and-push :
16+ runs-on : ubuntu-latest
17+ permissions :
18+ contents : read
19+ packages : write
20+
21+ steps :
22+ - name : Checkout repository
23+ uses : actions/checkout@v4
24+
25+ - name : Log in to Container Registry
26+ uses : docker/login-action@v3
27+ with :
28+ registry : ${{ env.REGISTRY }}
29+ username : ${{ github.actor }}
30+ password : ${{ secrets.GITHUB_TOKEN }}
31+
32+ - name : Set up Docker Buildx
33+ uses : docker/setup-buildx-action@v3
34+
35+ - name : Extract metadata for frontend
36+ id : meta-frontend
37+ uses : docker/metadata-action@v5
38+ with :
39+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}
40+ tags : |
41+ type=ref,event=branch
42+ type=ref,event=pr
43+ type=sha,prefix={{branch}}-
44+ type=raw,value=latest,enable={{is_default_branch}}
45+
46+ - name : Extract metadata for backend
47+ id : meta-backend
48+ uses : docker/metadata-action@v5
49+ with :
50+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}
51+ tags : |
52+ type=ref,event=branch
53+ type=ref,event=pr
54+ type=sha,prefix={{branch}}-
55+ type=raw,value=latest,enable={{is_default_branch}}
56+
57+ - name : Build and push frontend image
58+ uses : docker/build-push-action@v5
59+ with :
60+ context : ./frontend
61+ file : ./frontend/Dockerfile
62+ push : true
63+ tags : ${{ steps.meta-frontend.outputs.tags }}
64+ labels : ${{ steps.meta-frontend.outputs.labels }}
65+ cache-from : type=gha
66+ cache-to : type=gha,mode=max
67+ platforms : linux/amd64,linux/arm64
68+
69+ - name : Build and push backend image
70+ uses : docker/build-push-action@v5
71+ with :
72+ context : ./backend
73+ file : ./backend/Dockerfile
74+ push : true
75+ tags : ${{ steps.meta-backend.outputs.tags }}
76+ labels : ${{ steps.meta-backend.outputs.labels }}
77+ cache-from : type=gha
78+ cache-to : type=gha,mode=max
79+ platforms : linux/amd64,linux/arm64
80+
81+ security-scan :
82+ runs-on : ubuntu-latest
83+ needs : build-and-push
84+ if : github.event_name == 'push'
85+
86+ steps :
87+ - name : Run Trivy vulnerability scanner for frontend
88+ uses : aquasecurity/trivy-action@master
89+ with :
90+ image-ref : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:latest
91+ format : ' sarif'
92+ output : ' trivy-frontend-results.sarif'
93+
94+ - name : Run Trivy vulnerability scanner for backend
95+ uses : aquasecurity/trivy-action@master
96+ with :
97+ image-ref : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:latest
98+ format : ' sarif'
99+ output : ' trivy-backend-results.sarif'
100+
101+ - name : Upload Trivy scan results to GitHub Security tab
102+ uses : github/codeql-action/upload-sarif@v3
103+ if : always()
104+ with :
105+ sarif_file : ' .'
106+
107+ deploy :
108+ runs-on : ubuntu-latest
109+ needs : build-and-push
110+ if : github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
111+ environment : production
112+
113+ steps :
114+ - name : Checkout repository
115+ uses : actions/checkout@v4
116+
117+ - name : Create deployment package
118+ run : |
119+ mkdir -p deploy
120+ cp docker-compose.yml deploy/
121+ cp -r backend/.env deploy/backend.env
122+
123+ # 更新docker-compose.yml中的镜像标签
124+ sed -i "s|image: kb_frontend|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:latest|g" deploy/docker-compose.yml
125+ sed -i "s|image: kb_backend|image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:latest|g" deploy/docker-compose.yml
126+
127+ - name : Upload deployment artifacts
128+ uses : actions/upload-artifact@v4
129+ with :
130+ name : deployment-package
131+ path : deploy/
132+ retention-days : 30
133+
134+ # 如果你有服务器部署,可以添加以下步骤
135+ # - name: Deploy to server
136+ # uses: appleboy/ssh-action@v1.0.0
137+ # with:
138+ # host: ${{ secrets.HOST }}
139+ # username: ${{ secrets.USERNAME }}
140+ # key: ${{ secrets.SSH_KEY }}
141+ # script: |
142+ # cd /path/to/deployment
143+ # docker compose pull
144+ # docker compose up -d
145+ # docker system prune -f
146+
147+ notify :
148+ runs-on : ubuntu-latest
149+ needs : [build-and-push, deploy]
150+ if : always()
151+
152+ steps :
153+ - name : Notify deployment status
154+ run : |
155+ if [ "${{ needs.build-and-push.result }}" == "success" ] && [ "${{ needs.deploy.result }}" == "success" ]; then
156+ echo "✅ 部署成功!"
157+ echo "前端镜像: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_FRONTEND }}:latest"
158+ echo "后端镜像: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME_BACKEND }}:latest"
159+ else
160+ echo "❌ 部署失败,请检查日志"
161+ exit 1
162+ fi
0 commit comments