Skip to content

Commit f08612f

Browse files
committed
feat: 添加 Docker 支持和 GitHub Actions 自动构建
- 添加 Dockerfile(支持 CPU 和 GPU 版本) - 添加 .dockerignore 优化构建 - 添加 docker-compose.yml 简化部署 - 添加 GitHub Actions 工作流自动构建并推送到 Docker Hub - 支持通过环境变量配置管理员密码 - CPU 版本约 1GB,GPU 版本约 6GB
1 parent 2d270d0 commit f08612f

4 files changed

Lines changed: 374 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
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+
workflow_dispatch:
13+
inputs:
14+
push_to_registry:
15+
description: 'Push to Docker registry'
16+
required: true
17+
default: 'true'
18+
type: choice
19+
options:
20+
- 'true'
21+
- 'false'
22+
23+
env:
24+
# Docker Hub 用户名(需要在 GitHub Secrets 中设置 DOCKERHUB_USERNAME)
25+
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
26+
# 镜像名称(可以修改为你的 Docker Hub 仓库名)
27+
IMAGE_NAME: manga-translator
28+
29+
jobs:
30+
build-and-push:
31+
runs-on: ubuntu-latest
32+
33+
strategy:
34+
matrix:
35+
build_type: [cpu, gpu]
36+
37+
steps:
38+
- name: Checkout repository
39+
uses: actions/checkout@v4
40+
41+
- name: Set up QEMU
42+
uses: docker/setup-qemu-action@v3
43+
44+
- name: Set up Docker Buildx
45+
uses: docker/setup-buildx-action@v3
46+
47+
- name: Log in to Docker Hub
48+
if: github.event_name != 'pull_request'
49+
uses: docker/login-action@v3
50+
with:
51+
username: ${{ secrets.DOCKERHUB_USERNAME }}
52+
password: ${{ secrets.DOCKERHUB_TOKEN }}
53+
54+
- name: Extract metadata
55+
id: meta
56+
uses: docker/metadata-action@v5
57+
with:
58+
images: ${{ env.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}
59+
tags: |
60+
type=ref,event=branch,suffix=-${{ matrix.build_type }}
61+
type=ref,event=pr,suffix=-${{ matrix.build_type }}
62+
type=semver,pattern={{version}},suffix=-${{ matrix.build_type }}
63+
type=semver,pattern={{major}}.{{minor}},suffix=-${{ matrix.build_type }}
64+
type=raw,value=latest-${{ matrix.build_type }},enable={{is_default_branch}}
65+
flavor: |
66+
latest=false
67+
68+
- name: Build and push Docker image
69+
id: build
70+
uses: docker/build-push-action@v5
71+
with:
72+
context: .
73+
file: ./packaging/Dockerfile
74+
push: ${{ github.event_name != 'pull_request' && (github.event.inputs.push_to_registry != 'false') }}
75+
tags: ${{ steps.meta.outputs.tags }}
76+
labels: ${{ steps.meta.outputs.labels }}
77+
build-args: |
78+
BUILD_TYPE=${{ matrix.build_type }}
79+
CUDA_VERSION=12.1.0
80+
PYTHON_VERSION=3.12
81+
cache-from: type=gha
82+
cache-to: type=gha,mode=max
83+
platforms: linux/amd64
84+
85+
- name: Image digest
86+
run: echo ${{ steps.build.outputs.digest }}

packaging/.dockerignore

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
MANIFEST
23+
24+
# Virtual environments
25+
venv/
26+
venv_wsl/
27+
ENV/
28+
env/
29+
conda_env/
30+
Miniconda3/
31+
32+
# IDE
33+
.vscode/
34+
.idea/
35+
.kiro/
36+
.claude/
37+
*.swp
38+
*.swo
39+
*~
40+
41+
# Git
42+
.git/
43+
.gitignore
44+
.gitattributes
45+
46+
# Docker
47+
Dockerfile
48+
.dockerignore
49+
docker-compose.yml
50+
51+
# Build artifacts
52+
packaging/build/
53+
packaging/dist/
54+
*.spec
55+
56+
# Logs
57+
logs/
58+
*.log
59+
60+
# Test files
61+
test/
62+
tests/
63+
*.test.py
64+
65+
# Documentation
66+
doc/
67+
*.md
68+
!README.md
69+
70+
# Examples (keep config files)
71+
examples/*.jpg
72+
examples/*.png
73+
examples/*.webp
74+
75+
# Results and uploads
76+
result/
77+
upload-cache/
78+
uploads/
79+
originals/
80+
memory_profiles/
81+
82+
# Models (will be downloaded at runtime)
83+
models/*
84+
!models/.gitkeep
85+
86+
# Temporary files
87+
*.tmp
88+
*.bak
89+
*.swp
90+
.DS_Store
91+
Thumbs.db
92+
93+
# Windows batch files
94+
*.bat
95+
96+
# Other projects
97+
ailab-main/
98+
BallonsTranslator-dev/
99+
manga-image-translator-rust-master/
100+
manga-translator-ui-1.7.6/
101+
manga_decrypt/
102+
pydensecrf/
103+
resources (1)/
104+
105+
# Wheels
106+
*.whl

packaging/Dockerfile

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Manga Translator Docker Image
2+
# 支持 CPU 和 GPU 版本
3+
4+
ARG CUDA_VERSION=12.1.0
5+
ARG PYTHON_VERSION=3.12
6+
ARG BUILD_TYPE=cpu
7+
8+
# ===== CPU 版本 =====
9+
FROM python:${PYTHON_VERSION}-slim AS base-cpu
10+
11+
# 安装系统依赖
12+
RUN apt-get update && apt-get install -y \
13+
git \
14+
wget \
15+
curl \
16+
build-essential \
17+
libgl1-mesa-glx \
18+
libglib2.0-0 \
19+
libsm6 \
20+
libxext6 \
21+
libxrender-dev \
22+
libgomp1 \
23+
&& rm -rf /var/lib/apt/lists/*
24+
25+
# ===== GPU 版本 =====
26+
FROM nvidia/cuda:${CUDA_VERSION}-cudnn8-runtime-ubuntu22.04 AS base-gpu
27+
28+
# 安装 Python 3.12
29+
RUN apt-get update && apt-get install -y \
30+
software-properties-common \
31+
&& add-apt-repository ppa:deadsnakes/ppa \
32+
&& apt-get update && apt-get install -y \
33+
python3.12 \
34+
python3.12-dev \
35+
python3.12-distutils \
36+
python3-pip \
37+
git \
38+
wget \
39+
curl \
40+
build-essential \
41+
libgl1-mesa-glx \
42+
libglib2.0-0 \
43+
libsm6 \
44+
libxext6 \
45+
libxrender-dev \
46+
libgomp1 \
47+
&& rm -rf /var/lib/apt/lists/*
48+
49+
# 设置 Python 3.12 为默认
50+
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1 \
51+
&& update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1
52+
53+
# 升级 pip
54+
RUN python -m pip install --upgrade pip
55+
56+
# ===== 选择基础镜像 =====
57+
FROM base-${BUILD_TYPE} AS base
58+
59+
# 设置工作目录
60+
WORKDIR /app
61+
62+
# 复制项目文件
63+
COPY . /app/
64+
65+
# 安装 Python 依赖
66+
ARG BUILD_TYPE=cpu
67+
RUN if [ "$BUILD_TYPE" = "gpu" ]; then \
68+
# GPU 版本:先安装 pydensecrf 从源码,然后安装其他依赖
69+
pip install --no-cache-dir Cython numpy && \
70+
pip install --no-cache-dir git+https://github.com/lucasb-eyer/pydensecrf.git && \
71+
grep -v "pydensecrf" requirements_gpu.txt > /tmp/requirements_gpu_no_pydensecrf.txt && \
72+
pip install --no-cache-dir -r /tmp/requirements_gpu_no_pydensecrf.txt; \
73+
else \
74+
# CPU 版本:先安装 pydensecrf 从源码,然后安装其他依赖
75+
pip install --no-cache-dir Cython numpy && \
76+
pip install --no-cache-dir git+https://github.com/lucasb-eyer/pydensecrf.git && \
77+
grep -v "pydensecrf" requirements_cpu.txt > /tmp/requirements_cpu_no_pydensecrf.txt && \
78+
pip install --no-cache-dir -r /tmp/requirements_cpu_no_pydensecrf.txt; \
79+
fi
80+
81+
# 创建必要的目录
82+
RUN mkdir -p /app/fonts /app/dict /app/result /app/models /app/logs
83+
84+
# 设置环境变量
85+
ENV PYTHONUNBUFFERED=1
86+
ENV MANGA_TRANSLATOR_WEB_SERVER=true
87+
88+
# 暴露端口
89+
EXPOSE 8000
90+
91+
# 健康检查
92+
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
93+
CMD curl -f http://localhost:8000/ || exit 1
94+
95+
# 启动命令
96+
CMD ["python", "-m", "manga_translator", "web", "--host", "0.0.0.0", "--port", "8000"]

packaging/docker-compose.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
version: '3.8'
2+
3+
services:
4+
# CPU 版本
5+
manga-translator-cpu:
6+
build:
7+
context: ..
8+
dockerfile: packaging/Dockerfile
9+
args:
10+
BUILD_TYPE: cpu
11+
image: manga-translator:cpu
12+
container_name: manga-translator-cpu
13+
ports:
14+
- "8000:8000"
15+
environment:
16+
- MT_WEB_HOST=0.0.0.0
17+
- MT_WEB_PORT=8000
18+
- MT_USE_GPU=false
19+
- MT_MODELS_TTL=0
20+
- MT_RETRY_ATTEMPTS=-1
21+
- MT_VERBOSE=false
22+
# 设置管理员密码(首次启动)
23+
- MANGA_TRANSLATOR_ADMIN_PASSWORD=admin123456
24+
volumes:
25+
# 持久化数据
26+
- ./data/fonts:/app/fonts
27+
- ./data/dict:/app/dict
28+
- ./data/result:/app/result
29+
- ./data/models:/app/models
30+
- ./data/logs:/app/logs
31+
# 配置文件
32+
- ./data/config:/app/examples
33+
- ./data/admin_config.json:/app/manga_translator/server/admin_config.json
34+
restart: unless-stopped
35+
healthcheck:
36+
test: ["CMD", "curl", "-f", "http://localhost:8000/"]
37+
interval: 30s
38+
timeout: 10s
39+
retries: 3
40+
start_period: 60s
41+
42+
# GPU 版本
43+
manga-translator-gpu:
44+
build:
45+
context: ..
46+
dockerfile: packaging/Dockerfile
47+
args:
48+
BUILD_TYPE: gpu
49+
CUDA_VERSION: 12.1.0
50+
image: manga-translator:gpu
51+
container_name: manga-translator-gpu
52+
ports:
53+
- "8001:8000"
54+
environment:
55+
- MT_WEB_HOST=0.0.0.0
56+
- MT_WEB_PORT=8000
57+
- MT_USE_GPU=true
58+
- MT_MODELS_TTL=300
59+
- MT_RETRY_ATTEMPTS=-1
60+
- MT_VERBOSE=false
61+
# 设置管理员密码(首次启动)
62+
- MANGA_TRANSLATOR_ADMIN_PASSWORD=admin123456
63+
volumes:
64+
# 持久化数据
65+
- ./data/fonts:/app/fonts
66+
- ./data/dict:/app/dict
67+
- ./data/result:/app/result
68+
- ./data/models:/app/models
69+
- ./data/logs:/app/logs
70+
# 配置文件
71+
- ./data/config:/app/examples
72+
- ./data/admin_config.json:/app/manga_translator/server/admin_config.json
73+
deploy:
74+
resources:
75+
reservations:
76+
devices:
77+
- driver: nvidia
78+
count: all
79+
capabilities: [gpu]
80+
restart: unless-stopped
81+
healthcheck:
82+
test: ["CMD", "curl", "-f", "http://localhost:8000/"]
83+
interval: 30s
84+
timeout: 10s
85+
retries: 3
86+
start_period: 60s

0 commit comments

Comments
 (0)