Skip to content

Commit 56d82be

Browse files
authored
Merge pull request #14 from liueic/feat/docker
feat: Add support of docker
2 parents 89ab51a + 5d759b5 commit 56d82be

27 files changed

+943
-211
lines changed

.eslintrc.cjs

Lines changed: 0 additions & 29 deletions
This file was deleted.
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# FastAPI SQLAlchemy 模块缺失问题修复
2+
3+
## Core Features
4+
5+
- 诊断模块缺失问题
6+
7+
- 安装缺失依赖
8+
9+
- 验证服务启动
10+
11+
- 依赖管理优化
12+
13+
## Tech Stack
14+
15+
{
16+
"Backend": "Python + FastAPI + SQLAlchemy + Uvicorn",
17+
"Package Manager": "pip + requirements.txt",
18+
"Environment": "Python虚拟环境"
19+
}
20+
21+
## Plan
22+
23+
Note:
24+
25+
- [ ] is holding
26+
- [/] is doing
27+
- [X] is done
28+
29+
---
30+
31+
[X] 检查当前 Python 环境和虚拟环境状态
32+
33+
[X] 验证 requirements.txt 文件内容和依赖列表
34+
35+
[X] 安装缺失的 SQLAlchemy 及相关依赖包
36+
37+
[/] 验证依赖安装是否成功
38+
39+
[ ] 启动 FastAPI 服务并确认问题解决
40+
41+
[ ] 提供依赖管理最佳实践建议
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# FastAPI 后端项目依赖管理修复
2+
3+
## Core Features
4+
5+
- uv 包管理器配置
6+
7+
- 虚拟环境激活
8+
9+
- requirements.txt 依赖修复
10+
11+
- 核心库安装验证
12+
13+
- 项目启动测试
14+
15+
## Tech Stack
16+
17+
{
18+
"包管理器": "uv",
19+
"Python环境": ".venv 虚拟环境",
20+
"Web框架": "FastAPI",
21+
"数据库ORM": "SQLAlchemy",
22+
"缓存": "Redis",
23+
"测试框架": "pytest"
24+
}
25+
26+
## Plan
27+
28+
Note:
29+
30+
- [ ] is holding
31+
- [/] is doing
32+
- [X] is done
33+
34+
---
35+
36+
[X] 检查当前项目结构和 requirements.txt 文件内容
37+
38+
[X] 安装和配置 uv 包管理器
39+
40+
[X] 激活 .venv 虚拟环境
41+
42+
[X] 分析并修复 requirements.txt 依赖问题
43+
44+
[X] 使用 uv 安装所有依赖包
45+
46+
[X] 验证依赖安装和项目启动

backend/Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# 后端容器 - KB Upload Genie Backend
2+
FROM python:3.12-slim-bullseye
3+
4+
# 设置工作目录
5+
WORKDIR /app
6+
7+
# 安装系统依赖
8+
RUN apt-get update && apt-get install -y \
9+
gcc \
10+
g++ \
11+
curl \
12+
libmagic1 \
13+
libmagic-dev \
14+
&& rm -rf /var/lib/apt/lists/*
15+
16+
# 创建非root用户
17+
RUN groupadd -g 1001 appgroup && \
18+
useradd -r -u 1001 -g appgroup appuser
19+
20+
# 复制依赖文件
21+
COPY requirements.txt .
22+
23+
# 安装Python依赖
24+
RUN pip install --no-cache-dir -r requirements.txt
25+
26+
# 复制应用代码
27+
COPY . .
28+
29+
# 创建必要的目录
30+
RUN mkdir -p uploads logs && \
31+
chown -R appuser:appgroup /app
32+
33+
# 切换到非root用户
34+
USER appuser
35+
36+
# 暴露端口
37+
EXPOSE 8002
38+
39+
# 健康检查
40+
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
41+
CMD curl -f http://localhost:8002/health || exit 1
42+
43+
# 启动命令
44+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8002", "--reload"]

backend/app/api/deps.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
from sqlalchemy.ext.asyncio import AsyncSession
1010
from sqlalchemy import select
1111
from jose import JWTError
12+
"""
13+
API依赖项
14+
提供通用的依赖注入函数
15+
"""
16+
17+
from typing import Generator, Optional
18+
from fastapi import Depends, HTTPException, status
19+
from fastapi.security import OAuth2PasswordBearer
20+
from sqlalchemy.ext.asyncio import AsyncSession
21+
from sqlalchemy import select
1222
import logging
1323

1424
from app.core.database import AsyncSessionLocal

0 commit comments

Comments
 (0)