Skip to content

Commit a26a6c1

Browse files
committed
feat: 添加 GitHub Actions 自动构建 Docker 镜像功能
1 parent d3680b4 commit a26a6c1

27 files changed

Lines changed: 1199 additions & 193 deletions

.dockerignore

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Git
2+
.git/
3+
.gitignore
4+
.gitattributes
5+
6+
# IDE
7+
.vscode/
8+
.idea/
9+
*.swp
10+
*.swo
11+
*~
12+
.DS_Store
13+
14+
# Documentation
15+
README.md
16+
docs/
17+
img/
18+
*.md
19+
20+
# Docker
21+
docker-compose*.yml
22+
.dockerignore
23+
24+
# Deployment scripts
25+
deploy-scripts/
26+
27+
# Logs
28+
*.log
29+
logs/
30+
31+
# Environment
32+
.env
33+
.env.*

.env.example

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Django 配置
2+
DJANGO_SECRET_KEY=your-secret-key-here-change-in-production
3+
DJANGO_DEBUG=False
4+
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1,your-domain.com
5+
DJANGO_CORS_ALLOWED_ORIGINS=http://localhost:80,https://your-domain.com
6+
7+
# Django 管理员账号(首次启动时自动创建)
8+
DJANGO_ADMIN_USERNAME=admin
9+
DJANGO_ADMIN_EMAIL=admin@example.com
10+
DJANGO_ADMIN_PASSWORD=admin123456
11+
12+
# 数据库配置(如果使用 PostgreSQL)
13+
# DATABASE_URL=postgresql://user:password@postgres:5432/wharttest
14+
15+
# MCP 服务配置
16+
17+
# MS MCP API 配置(如需使用 MS 测试平台集成,请取消注释并填写正确的密钥)
18+
# 注意:MS_SECRET_KEY 必须是 16、24 或 32 字节长度
19+
# MS_API_HOST=http://ms.example.com
20+
# MS_ACCESS_KEY=your_16byte_key1
21+
# MS_SECRET_KEY=your_16byte_key2
22+
23+
# WHartTest Tools 配置
24+
# Docker 环境使用: http://backend:8000
25+
# 本地开发使用: http://localhost:8000
26+
WHARTTEST_BACKEND_URL=http://backend:8000
27+
28+
# WHartTest API Key
29+
# 请在 WHartTest 平台的"API密钥管理"页面生成 API Key,然后填写到这里
30+
# 登录后访问:设置 -> API密钥管理 -> 创建新密钥
31+
WHARTTEST_API_KEY=your_api_key_here

.github/workflows/docker-build.yml

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Build and Push Docker Images
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- 'v*'
9+
pull_request:
10+
branches:
11+
- main
12+
13+
env:
14+
REGISTRY: ghcr.io
15+
IMAGE_BACKEND: ghcr.io/${{ github.repository_owner }}/wharttest-backend
16+
IMAGE_FRONTEND: ghcr.io/${{ github.repository_owner }}/wharttest-frontend
17+
IMAGE_MCP: ghcr.io/${{ github.repository_owner }}/wharttest-mcp
18+
19+
jobs:
20+
build-and-push:
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
packages: write
25+
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
30+
- name: Set up Docker Buildx
31+
uses: docker/setup-buildx-action@v3
32+
33+
- name: Log in to GitHub Container Registry
34+
if: github.event_name != 'pull_request'
35+
uses: docker/login-action@v3
36+
with:
37+
registry: ${{ env.REGISTRY }}
38+
username: ${{ github.actor }}
39+
password: ${{ secrets.GITHUB_TOKEN }}
40+
41+
- name: Extract metadata for backend
42+
id: meta-backend
43+
uses: docker/metadata-action@v5
44+
with:
45+
images: ${{ env.IMAGE_BACKEND }}
46+
tags: |
47+
type=ref,event=branch
48+
type=ref,event=pr
49+
type=semver,pattern={{version}}
50+
type=semver,pattern={{major}}.{{minor}}
51+
type=semver,pattern={{major}}
52+
type=raw,value=latest,enable={{is_default_branch}}
53+
54+
- name: Extract metadata for frontend
55+
id: meta-frontend
56+
uses: docker/metadata-action@v5
57+
with:
58+
images: ${{ env.IMAGE_FRONTEND }}
59+
tags: |
60+
type=ref,event=branch
61+
type=ref,event=pr
62+
type=semver,pattern={{version}}
63+
type=semver,pattern={{major}}.{{minor}}
64+
type=semver,pattern={{major}}
65+
type=raw,value=latest,enable={{is_default_branch}}
66+
67+
- name: Extract metadata for MCP
68+
id: meta-mcp
69+
uses: docker/metadata-action@v5
70+
with:
71+
images: ${{ env.IMAGE_MCP }}
72+
tags: |
73+
type=ref,event=branch
74+
type=ref,event=pr
75+
type=semver,pattern={{version}}
76+
type=semver,pattern={{major}}.{{minor}}
77+
type=semver,pattern={{major}}
78+
type=raw,value=latest,enable={{is_default_branch}}
79+
80+
- name: Build and push backend image
81+
uses: docker/build-push-action@v5
82+
with:
83+
context: ./WHartTest_Django
84+
file: ./WHartTest_Django/Dockerfile
85+
push: ${{ github.event_name != 'pull_request' }}
86+
tags: ${{ steps.meta-backend.outputs.tags }}
87+
labels: ${{ steps.meta-backend.outputs.labels }}
88+
cache-from: type=gha
89+
cache-to: type=gha,mode=max
90+
91+
- name: Build and push frontend image
92+
uses: docker/build-push-action@v5
93+
with:
94+
context: ./WHartTest_Vue
95+
file: ./WHartTest_Vue/Dockerfile
96+
push: ${{ github.event_name != 'pull_request' }}
97+
tags: ${{ steps.meta-frontend.outputs.tags }}
98+
labels: ${{ steps.meta-frontend.outputs.labels }}
99+
cache-from: type=gha
100+
cache-to: type=gha,mode=max
101+
102+
- name: Build and push MCP image
103+
uses: docker/build-push-action@v5
104+
with:
105+
context: ./WHartTest_MCP
106+
file: ./WHartTest_MCP/Dockerfile
107+
push: ${{ github.event_name != 'pull_request' }}
108+
tags: ${{ steps.meta-mcp.outputs.tags }}
109+
labels: ${{ steps.meta-mcp.outputs.labels }}
110+
cache-from: type=gha
111+
cache-to: type=gha,mode=max
112+
113+
- name: Image digest
114+
run: |
115+
echo "Backend: ${{ steps.meta-backend.outputs.tags }}"
116+
echo "Frontend: ${{ steps.meta-frontend.outputs.tags }}"
117+
echo "MCP: ${{ steps.meta-mcp.outputs.tags }}"

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ WHartTest 是一个基于 Django REST Framework 构建的AI驱动测试自动化
88
## 文档
99
详细文档请访问:https://mgdaaslab.github.io/WHartTest/
1010

11+
## 快速开始
12+
13+
### Docker 部署(推荐)
14+
15+
#### 使用预构建镜像(无需本地构建)
16+
```bash
17+
# 1. 克隆仓库
18+
git clone https://github.com/MG-Duan/WHartTest.git
19+
cd WHartTest
20+
21+
# 2. 配置环境变量
22+
cp .env.example .env
23+
# 编辑 .env 文件,设置必要的环境变量
24+
25+
# 3. 使用预构建镜像启动
26+
docker-compose -f docker-compose.prod.yml up -d
27+
```
28+
29+
#### 本地构建镜像(开发环境)
30+
```bash
31+
# 使用默认配置,会在本地构建镜像
32+
docker-compose up -d
33+
```
34+
35+
详细的部署说明请参考:
36+
- [GitHub 自动构建部署指南](./docs/github-docker-deployment.md)
37+
- [完整部署文档](https://mgdaaslab.github.io/WHartTest/)
38+
1139
## 页面展示
1240

1341
| | |

WHartTest_Django/.dockerignore

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,53 @@
1-
db.sqlite3
2-
*.sqlite3
3-
chat_history.sqlite
4-
chat_history.sqlite-shm
5-
chat_history.sqlite-wal
1+
# Python
62
__pycache__/
7-
*.pyc
8-
.env
9-
.DS_Store
10-
# 知识库数据
11-
knowledge/chroma_db/
12-
knowledge/documents/
13-
# 缓存目录(保留模型文件)
14-
.cache/pip/
15-
.cache/torch/
16-
.cache/transformers/checkpoints/
17-
# 用户上传文件
18-
media/
19-
# 旧版知识库数据
20-
knowledge_bases/
21-
# 日志文件
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
env/
8+
venv/
9+
ENV/
10+
env.bak/
11+
venv.bak/
12+
.venv/
13+
14+
# Django
2215
*.log
23-
logs/
16+
db.sqlite3
17+
db.sqlite3-journal
18+
media/
19+
staticfiles/
20+
21+
# IDE
22+
.vscode/
23+
.idea/
24+
*.swp
25+
*.swo
26+
*~
27+
.DS_Store
28+
29+
# Git
30+
.git/
31+
.gitignore
32+
.gitattributes
33+
34+
# Documentation
35+
README.md
36+
docs/
37+
*.md
38+
39+
# Tests
40+
.pytest_cache/
41+
.coverage
42+
htmlcov/
43+
.tox/
44+
45+
# Environment
46+
.env
47+
.env.local
48+
.env.*.local
49+
50+
# Docker
51+
Dockerfile
52+
.dockerignore
53+
docker-compose*.yml

WHartTest_Django/Dockerfile

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,39 @@
1-
FROM python:3.12-slim
1+
# 使用 Python 3.11 官方镜像作为基础镜像
2+
FROM python:3.11-slim
23

4+
# 设置工作目录
35
WORKDIR /app
46

5-
# 设置Hugging Face缓存目录
6-
ENV HF_HOME=/app/.cache/huggingface \
7-
HF_HUB_CACHE=/app/.cache/huggingface/hub
7+
# 设置环境变量
8+
ENV PYTHONUNBUFFERED=1 \
9+
PYTHONDONTWRITEBYTECODE=1 \
10+
PIP_NO_CACHE_DIR=1 \
11+
PIP_DISABLE_PIP_VERSION_CHECK=1
812

9-
# 使用国内镜像源加速
10-
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list.d/debian.sources
13+
# 安装系统依赖
14+
RUN apt-get update && apt-get install -y --no-install-recommends \
15+
build-essential \
16+
curl \
17+
git \
18+
&& rm -rf /var/lib/apt/lists/*
1119

12-
# 安装系统依赖(SQLite开发库)
13-
RUN apt-get update && apt-get install -y libsqlite3-dev
20+
# 安装 uv
21+
RUN pip install uv
1422

15-
# 复制依赖文件并安装
23+
# 复制 requirements 文件
1624
COPY requirements.txt .
17-
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
25+
26+
# 使用 uv 安装 Python 依赖
27+
RUN uv pip install --system -r requirements.txt
1828

1929
# 复制项目文件
2030
COPY . .
2131

22-
# 复制已有的模型缓存目录(如果存在)
23-
COPY .cache/huggingface /app/.cache/huggingface
32+
# 创建必要的目录
33+
RUN mkdir -p media static nltk_data
2434

35+
# 暴露端口
2536
EXPOSE 8000
2637

27-
# 设置默认超级用户环境变量
28-
ENV DJANGO_SUPERUSER_USERNAME=admin \
29-
DJANGO_SUPERUSER_PASSWORD=123456 \
30-
DJANGO_SUPERUSER_EMAIL=admin@qq.com
31-
32-
CMD ["sh", "-c", "python manage.py migrate && python manage.py createsuperuser --noinput || true && python manage.py runserver 0.0.0.0:8000"]
38+
# 启动命令
39+
CMD ["bash", "-c", "python manage.py migrate --noinput && python manage.py init_admin && python manage.py runserver 0.0.0.0:8000"]
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.core.management.base import BaseCommand
2+
from django.contrib.auth import get_user_model
3+
import os
4+
5+
User = get_user_model()
6+
7+
class Command(BaseCommand):
8+
help = '创建默认管理员账号'
9+
10+
def handle(self, *args, **options):
11+
# 从环境变量获取管理员信息
12+
admin_username = os.environ.get('DJANGO_ADMIN_USERNAME', 'admin')
13+
admin_email = os.environ.get('DJANGO_ADMIN_EMAIL', 'admin@example.com')
14+
admin_password = os.environ.get('DJANGO_ADMIN_PASSWORD', 'admin123456')
15+
16+
# 检查管理员是否已存在
17+
if User.objects.filter(username=admin_username).exists():
18+
self.stdout.write(
19+
self.style.WARNING(f'管理员账号 "{admin_username}" 已存在,跳过创建')
20+
)
21+
return
22+
23+
# 创建管理员账号
24+
User.objects.create_superuser(
25+
username=admin_username,
26+
email=admin_email,
27+
password=admin_password
28+
)
29+
30+
self.stdout.write(
31+
self.style.SUCCESS(
32+
f'成功创建管理员账号:\n'
33+
f' 用户名: {admin_username}\n'
34+
f' 邮箱: {admin_email}\n'
35+
f' 密码: {admin_password}'
36+
)
37+
)

0 commit comments

Comments
 (0)