概述
本文档详细介绍如何将 AI Backend Python 项目构建为 Docker 镜像并发布到各种 Docker 仓库,包括 Docker Hub、阿里云容器镜像服务、腾讯云容器镜像服务等。
1. 准备工作
1.1 环境要求
- Docker Desktop: 最新版本
- Git: 用于版本控制
- PowerShell: Windows 环境下的命令行工具
- 网络连接: 能够访问 Docker 仓库
1.2 项目文件检查
确保项目包含以下 Docker 相关文件:
bash
ai_backend_python/
├── Dockerfile # 生产环境镜像
├── Dockerfile.dev # 开发环境镜像
├── docker-compose.yml # 服务编排文件
├── docker-compose.dev.yml # 开发环境编排
├── .dockerignore # Docker 忽略文件
├── requirements.txt # Python 依赖
└── .env.example # 环境变量模板
1.3 创建 .dockerignore 文件
如果不存在,创建 .dockerignore
文件:
dockerignore
# .dockerignore
__pycache__
*.pyc
*.pyo
*.pyd
.Python
env
pip-log.txt
pip-delete-this-directory.txt
.tox
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.log
.git
.mypy_cache
.pytest_cache
.hypothesis
# 开发文件
.vscode
.idea
*.swp
*.swo
*~
# 环境文件
.env
.env.local
.env.*.local
# 数据库文件
*.db
*.sqlite
*.sqlite3
# 日志文件
logs/
*.log
# 上传文件
uploads/
# 文档
docs/
README.md
# 测试文件
tests/
# 构建产物
build/
dist/
2. 本地构建和测试
2.1 构建生产镜像
powershell
# 进入项目目录
cd e:\project\ai-mini\ai_backend_python
# 构建生产镜像
docker build -t ai-mini-backend:latest .
# 构建带版本标签的镜像
docker build -t ai-mini-backend:v1.0.0 .
# 查看构建的镜像
docker images | Select-String "ai-mini-backend"
2.2 构建开发镜像
powershell
# 构建开发镜像
docker build -f Dockerfile.dev -t ai-mini-backend:dev .
2.3 本地测试镜像
powershell
# 创建测试环境变量文件
Copy-Item .env.example .env.test
# 编辑 .env.test 文件,设置测试配置
# notepad .env.test
# 运行容器进行测试
docker run -d `
--name test-backend `
-p 8000:8000 `
--env-file .env.test `
-v "${PWD}\uploads:/app/uploads" `
ai-mini-backend:latest
# 等待容器启动
Start-Sleep -Seconds 10
# 检查容器状态
docker ps
# 查看容器日志
docker logs test-backend
# 测试健康检查端点
Invoke-WebRequest -Uri "http://localhost:8000/health" -Method GET
# 测试 API 端点
Invoke-WebRequest -Uri "http://localhost:8000/api/v1/health" -Method GET
# 停止并删除测试容器
docker stop test-backend
docker rm test-backend
2.4 使用 Docker Compose 测试
powershell
# 使用 docker-compose 启动完整服务
docker-compose up -d
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f ai-backend
# 停止服务
docker-compose down
3. 发布到 Docker Hub
3.1 注册 Docker Hub 账号
- 访问 Docker Hub
- 注册账号或登录现有账号
- 创建新的仓库(Repository)
3.2 登录 Docker Hub
powershell
# 登录 Docker Hub
docker login
# 输入用户名和密码
3.3 标记镜像
powershell
# 替换 yourusername 为您的 Docker Hub 用户名
$dockerUsername = "yourusername"
$imageName = "ai-mini-backend"
$version = "v1.0.0"
# 标记镜像
docker tag ai-mini-backend:latest "${dockerUsername}/${imageName}:latest"
docker tag ai-mini-backend:latest "${dockerUsername}/${imageName}:${version}"
# 查看标记的镜像
docker images | Select-String $imageName
3.4 推送镜像
powershell
# 推送最新版本
docker push "${dockerUsername}/${imageName}:latest"
# 推送特定版本
docker push "${dockerUsername}/${imageName}:${version}"
# 验证推送结果
Write-Host "镜像已成功推送到 Docker Hub" -ForegroundColor Green
Write-Host "镜像地址: ${dockerUsername}/${imageName}:${version}" -ForegroundColor Cyan
4. 发布到私有仓库
4.1 阿里云容器镜像服务
4.1.1 准备工作
- 登录 阿里云控制台
- 开通容器镜像服务
- 创建命名空间和镜像仓库
- 获取访问凭证
4.1.2 登录和推送
powershell
# 设置阿里云镜像仓库信息
$aliRegistry = "registry.cn-hangzhou.aliyuncs.com"
$aliNamespace = "your-namespace"
$aliUsername = "your-username"
# 登录阿里云镜像仓库
docker login --username=$aliUsername $aliRegistry
# 标记镜像
docker tag ai-mini-backend:latest "${aliRegistry}/${aliNamespace}/ai-mini-backend:latest"
docker tag ai-mini-backend:latest "${aliRegistry}/${aliNamespace}/ai-mini-backend:${version}"
# 推送镜像
docker push "${aliRegistry}/${aliNamespace}/ai-mini-backend:latest"
docker push "${aliRegistry}/${aliNamespace}/ai-mini-backend:${version}"
4.2 腾讯云容器镜像服务
4.2.1 准备工作
- 登录 腾讯云控制台
- 开通容器镜像服务
- 创建命名空间和镜像仓库
- 获取访问凭证
4.2.2 登录和推送
powershell
# 设置腾讯云镜像仓库信息
$tencentRegistry = "ccr.ccs.tencentyun.com"
$tencentNamespace = "your-namespace"
$tencentUsername = "your-username"
# 登录腾讯云镜像仓库
docker login --username=$tencentUsername $tencentRegistry
# 标记镜像
docker tag ai-mini-backend:latest "${tencentRegistry}/${tencentNamespace}/ai-mini-backend:latest"
docker tag ai-mini-backend:latest "${tencentRegistry}/${tencentNamespace}/ai-mini-backend:${version}"
# 推送镜像
docker push "${tencentRegistry}/${tencentNamespace}/ai-mini-backend:latest"
docker push "${tencentRegistry}/${tencentNamespace}/ai-mini-backend:${version}"
4.3 私有 Docker Registry
powershell
# 设置私有仓库信息
$privateRegistry = "your-private-registry.com:5000"
# 登录私有仓库(如果需要认证)
docker login $privateRegistry
# 标记镜像
docker tag ai-mini-backend:latest "${privateRegistry}/ai-mini-backend:latest"
docker tag ai-mini-backend:latest "${privateRegistry}/ai-mini-backend:${version}"
# 推送镜像
docker push "${privateRegistry}/ai-mini-backend:latest"
docker push "${privateRegistry}/ai-mini-backend:${version}"
5. 自动化发布
5.1 PowerShell 发布脚本
创建 scripts/docker-publish.ps1
:
powershell
<#
.SYNOPSIS
AI Mini Backend Docker 镜像发布脚本
.DESCRIPTION
自动构建、标记和推送 Docker 镜像到指定仓库
.PARAMETER Version
镜像版本号,例如 "v1.0.0"
.PARAMETER Registry
Docker 仓库地址,默认为 "docker.io"
.PARAMETER Username
Docker 仓库用户名
.PARAMETER Namespace
命名空间(用于阿里云、腾讯云等)
.PARAMETER ImageName
镜像名称,默认为 "ai-mini-backend"
.PARAMETER PushLatest
是否推送 latest 标签,默认为 true
.EXAMPLE
.\scripts\docker-publish.ps1 -Version "v1.0.0" -Username "myusername"
.EXAMPLE
.\scripts\docker-publish.ps1 -Version "v1.0.0" -Registry "registry.cn-hangzhou.aliyuncs.com" -Username "myusername" -Namespace "mynamespace"
#>
param(
[Parameter(Mandatory=$true)]
[string]$Version,
[Parameter(Mandatory=$false)]
[string]$Registry = "docker.io",
[Parameter(Mandatory=$true)]
[string]$Username,
[Parameter(Mandatory=$false)]
[string]$Namespace = "",
[Parameter(Mandatory=$false)]
[string]$ImageName = "ai-mini-backend",
[Parameter(Mandatory=$false)]
[bool]$PushLatest = $true,
[Parameter(Mandatory=$false)]
[bool]$BuildImage = $true,
[Parameter(Mandatory=$false)]
[string]$Dockerfile = "Dockerfile"
)
# 设置错误处理
$ErrorActionPreference = "Stop"
# 函数:写入彩色日志
function Write-ColorLog {
param(
[string]$Message,
[string]$Color = "White"
)
Write-Host "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message" -ForegroundColor $Color
}
# 函数:检查命令是否存在
function Test-Command {
param([string]$Command)
try {
Get-Command $Command -ErrorAction Stop
return $true
} catch {
return $false
}
}
# 检查 Docker 是否安装
if (-not (Test-Command "docker")) {
Write-ColorLog "错误: Docker 未安装或不在 PATH 中" "Red"
exit 1
}
# 检查 Docker 是否运行
try {
docker version | Out-Null
} catch {
Write-ColorLog "错误: Docker 服务未运行" "Red"
exit 1
}
Write-ColorLog "开始发布 AI Mini Backend Docker 镜像..." "Green"
Write-ColorLog "版本: $Version" "Cyan"
Write-ColorLog "仓库: $Registry" "Cyan"
Write-ColorLog "用户名: $Username" "Cyan"
# 构建完整的镜像名称
if ($Namespace) {
$fullImageName = "$Registry/$Namespace/$ImageName"
} else {
if ($Registry -eq "docker.io") {
$fullImageName = "$Username/$ImageName"
} else {
$fullImageName = "$Registry/$Username/$ImageName"
}
}
Write-ColorLog "完整镜像名称: $fullImageName" "Cyan"
# 构建镜像
if ($BuildImage) {
Write-ColorLog "开始构建镜像..." "Yellow"
try {
docker build -f $Dockerfile -t "${ImageName}:${Version}" .
if ($LASTEXITCODE -ne 0) {
throw "Docker build failed"
}
Write-ColorLog "镜像构建成功" "Green"
} catch {
Write-ColorLog "镜像构建失败: $_" "Red"
exit 1
}
}
# 标记镜像
Write-ColorLog "开始标记镜像..." "Yellow"
try {
# 标记版本镜像
docker tag "${ImageName}:${Version}" "${fullImageName}:${Version}"
if ($LASTEXITCODE -ne 0) {
throw "Failed to tag version image"
}
# 标记 latest 镜像
if ($PushLatest) {
docker tag "${ImageName}:${Version}" "${fullImageName}:latest"
if ($LASTEXITCODE -ne 0) {
throw "Failed to tag latest image"
}
}
Write-ColorLog "镜像标记完成" "Green"
} catch {
Write-ColorLog "镜像标记失败: $_" "Red"
exit 1
}
# 登录 Docker 仓库
Write-ColorLog "登录 Docker 仓库..." "Yellow"
try {
if ($Registry -ne "docker.io") {
docker login $Registry
} else {
docker login
}
if ($LASTEXITCODE -ne 0) {
throw "Docker login failed"
}
Write-ColorLog "登录成功" "Green"
} catch {
Write-ColorLog "登录失败: $_" "Red"
exit 1
}
# 推送镜像
Write-ColorLog "开始推送镜像..." "Yellow"
try {
# 推送版本镜像
Write-ColorLog "推送版本镜像: ${fullImageName}:${Version}" "Cyan"
docker push "${fullImageName}:${Version}"
if ($LASTEXITCODE -ne 0) {
throw "Failed to push version image"
}
# 推送 latest 镜像
if ($PushLatest) {
Write-ColorLog "推送 latest 镜像: ${fullImageName}:latest" "Cyan"
docker push "${fullImageName}:latest"
if ($LASTEXITCODE -ne 0) {
throw "Failed to push latest image"
}
}
Write-ColorLog "镜像推送成功!" "Green"
Write-ColorLog "镜像地址:" "White"
Write-ColorLog " - ${fullImageName}:${Version}" "Cyan"
if ($PushLatest) {
Write-ColorLog " - ${fullImageName}:latest" "Cyan"
}
} catch {
Write-ColorLog "镜像推送失败: $_" "Red"
exit 1
}
# 清理本地镜像(可选)
$cleanup = Read-Host "是否清理本地构建的镜像? (y/N)"
if ($cleanup -eq "y" -or $cleanup -eq "Y") {
Write-ColorLog "清理本地镜像..." "Yellow"
try {
docker rmi "${ImageName}:${Version}" -f
docker rmi "${fullImageName}:${Version}" -f
if ($PushLatest) {
docker rmi "${fullImageName}:latest" -f
}
Write-ColorLog "本地镜像清理完成" "Green"
} catch {
Write-ColorLog "清理本地镜像时出现警告: $_" "Yellow"
}
}
Write-ColorLog "Docker 镜像发布完成!" "Green"
5.2 使用发布脚本
powershell
# 设置执行策略(首次使用时)
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# 发布到 Docker Hub
.\scripts\docker-publish.ps1 -Version "v1.0.0" -Username "yourusername"
# 发布到阿里云
.\scripts\docker-publish.ps1 `
-Version "v1.0.0" `
-Registry "registry.cn-hangzhou.aliyuncs.com" `
-Username "your-aliyun-username" `
-Namespace "your-namespace"
# 发布到腾讯云
.\scripts\docker-publish.ps1 `
-Version "v1.0.0" `
-Registry "ccr.ccs.tencentyun.com" `
-Username "your-tencent-username" `
-Namespace "your-namespace"
# 只推送,不重新构建
.\scripts\docker-publish.ps1 `
-Version "v1.0.0" `
-Username "yourusername" `
-BuildImage $false
5.3 GitHub Actions 自动发布
创建 .github/workflows/docker-publish.yml
:
yaml
name: Build and Push Docker Image
on:
push:
tags:
- 'v*'
release:
types: [published]
workflow_dispatch:
inputs:
version:
description: 'Version to build and push'
required: true
default: 'latest'
env:
REGISTRY: docker.io
IMAGE_NAME: ai-mini-backend
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=tag
type=raw,value=latest,enable={{is_default_branch}}
type=raw,value=${{ github.event.inputs.version }},enable=${{ github.event_name == 'workflow_dispatch' }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./ai_backend_python
file: ./ai_backend_python/Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
- name: Update deployment
if: github.ref == 'refs/heads/main'
run: |
echo "Deployment updated with new image: ${{ steps.meta.outputs.tags }}"
# 这里可以添加自动部署逻辑
5.4 配置 GitHub Secrets
在 GitHub 仓库设置中添加以下 Secrets:
DOCKER_USERNAME
: Docker Hub 用户名DOCKER_PASSWORD
: Docker Hub 密码或访问令牌
6. 镜像优化
6.1 多阶段构建优化
创建优化的 Dockerfile.optimized
:
dockerfile
# AI Mini Backend Python - 优化的多阶段构建
# 构建阶段
FROM python:3.11-slim as builder
# 设置工作目录
WORKDIR /app
# 安装构建依赖
RUN apt-get update && apt-get install -y \
gcc \
default-libmysqlclient-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
# 复制并安装 Python 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
# 运行时阶段
FROM python:3.11-slim as runtime
# 设置工作目录
WORKDIR /app
# 安装运行时依赖
RUN apt-get update && apt-get install -y \
default-libmysqlclient-dev \
curl \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# 从构建阶段复制已安装的依赖
COPY --from=builder /root/.local /root/.local
# 复制应用代码
COPY src/ ./src/
COPY scripts/ ./scripts/
COPY .env.example .
# 创建必要目录
RUN mkdir -p uploads logs
# 创建非 root 用户
RUN useradd --create-home --shell /bin/bash app && \
chown -R app:app /app
USER app
# 设置环境变量
ENV PATH=/root/.local/bin:$PATH
ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1
ENV ENVIRONMENT=production
# 暴露端口
EXPOSE 8000
# 健康检查
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1
# 启动命令
CMD ["python", "scripts/start.py", "--env", "prod"]
6.2 镜像大小优化
powershell
# 构建优化镜像
docker build -f Dockerfile.optimized -t ai-mini-backend:optimized .
# 比较镜像大小
docker images | Select-String "ai-mini-backend"
# 分析镜像层
docker history ai-mini-backend:optimized
6.3 安全扫描
powershell
# 使用 Docker Scout 扫描安全漏洞
docker scout cves ai-mini-backend:latest
# 使用 Trivy 扫描(需要先安装 Trivy)
# docker run --rm -v /var/run/docker.sock:/var/run/docker.sock `
# aquasec/trivy image ai-mini-backend:latest
7. 版本管理
7.1 语义化版本控制
采用 语义化版本 规范:
v1.0.0
- 主要版本(不兼容的 API 修改)v1.1.0
- 次要版本(向下兼容的功能性新增)v1.1.1
- 修订版本(向下兼容的问题修正)
7.2 标签策略
powershell
# 发布稳定版本
$version = "v1.0.0"
docker tag ai-mini-backend:latest "yourusername/ai-mini-backend:$version"
docker tag ai-mini-backend:latest "yourusername/ai-mini-backend:latest"
docker tag ai-mini-backend:latest "yourusername/ai-mini-backend:stable"
# 发布预发布版本
$preVersion = "v1.1.0-beta.1"
docker tag ai-mini-backend:latest "yourusername/ai-mini-backend:$preVersion"
docker tag ai-mini-backend:latest "yourusername/ai-mini-backend:beta"
# 发布开发版本
docker tag ai-mini-backend:dev "yourusername/ai-mini-backend:dev"
docker tag ai-mini-backend:dev "yourusername/ai-mini-backend:nightly"
7.3 版本发布脚本
创建 scripts/release.ps1
:
powershell
<#
.SYNOPSIS
版本发布脚本
.DESCRIPTION
自动化版本发布流程,包括版本标记、构建、推送等
.PARAMETER Version
发布版本号
.PARAMETER Type
发布类型:major, minor, patch, prerelease
#>
param(
[Parameter(Mandatory=$false)]
[string]$Version,
[Parameter(Mandatory=$false)]
[ValidateSet("major", "minor", "patch", "prerelease")]
[string]$Type = "patch",
[Parameter(Mandatory=$true)]
[string]$Username
)
# 函数:获取当前版本
function Get-CurrentVersion {
try {
$tags = git tag --sort=-version:refname
if ($tags) {
return $tags[0]
} else {
return "v0.0.0"
}
} catch {
return "v0.0.0"
}
}
# 函数:计算下一个版本
function Get-NextVersion {
param(
[string]$CurrentVersion,
[string]$Type
)
# 移除 'v' 前缀
$version = $CurrentVersion -replace '^v', ''
$parts = $version -split '\.' | ForEach-Object { [int]$_ }
switch ($Type) {
"major" {
$parts[0]++
$parts[1] = 0
$parts[2] = 0
}
"minor" {
$parts[1]++
$parts[2] = 0
}
"patch" {
$parts[2]++
}
"prerelease" {
$parts[2]++
return "v$($parts[0]).$($parts[1]).$($parts[2])-beta.1"
}
}
return "v$($parts[0]).$($parts[1]).$($parts[2])"
}
# 获取版本信息
if (-not $Version) {
$currentVersion = Get-CurrentVersion
$Version = Get-NextVersion -CurrentVersion $currentVersion -Type $Type
Write-Host "当前版本: $currentVersion" -ForegroundColor Cyan
Write-Host "新版本: $Version" -ForegroundColor Green
$confirm = Read-Host "确认发布版本 $Version? (y/N)"
if ($confirm -ne "y" -and $confirm -ne "Y") {
Write-Host "发布已取消" -ForegroundColor Yellow
exit 0
}
}
Write-Host "开始发布版本 $Version..." -ForegroundColor Green
# 创建 Git 标签
try {
git tag $Version
git push origin $Version
Write-Host "Git 标签创建成功" -ForegroundColor Green
} catch {
Write-Host "Git 标签创建失败: $_" -ForegroundColor Red
exit 1
}
# 构建和推送 Docker 镜像
try {
& ".\scripts\docker-publish.ps1" -Version $Version -Username $Username
Write-Host "Docker 镜像发布成功" -ForegroundColor Green
} catch {
Write-Host "Docker 镜像发布失败: $_" -ForegroundColor Red
exit 1
}
Write-Host "版本 $Version 发布完成!" -ForegroundColor Green
8. 故障排除
8.1 常见问题
8.1.1 构建失败
powershell
# 清理 Docker 缓存
docker system prune -f
# 清理构建缓存
docker builder prune -f
# 重新构建(不使用缓存)
docker build --no-cache -t ai-mini-backend:latest .
8.1.2 推送失败
powershell
# 检查网络连接
Test-NetConnection -ComputerName "registry-1.docker.io" -Port 443
# 重新登录
docker logout
docker login
# 检查镜像标签
docker images | Select-String "ai-mini-backend"
8.1.3 权限问题
powershell
# 检查 Docker 用户组
# 在 Linux 系统中:
# groups $USER
# sudo usermod -aG docker $USER
# 在 Windows 中,确保 Docker Desktop 正在运行
Get-Process "Docker Desktop" -ErrorAction SilentlyContinue
8.2 调试技巧
8.2.1 进入容器调试
powershell
# 运行容器并进入 shell
docker run -it --entrypoint /bin/bash ai-mini-backend:latest
# 在运行的容器中执行命令
docker exec -it container_name /bin/bash
8.2.2 查看构建过程
powershell
# 详细构建日志
docker build --progress=plain -t ai-mini-backend:latest .
# 查看镜像层信息
docker history ai-mini-backend:latest
8.2.3 网络问题诊断
powershell
# 测试容器网络
docker run --rm ai-mini-backend:latest curl -I http://www.baidu.com
# 检查 DNS 解析
docker run --rm ai-mini-backend:latest nslookup google.com
8.3 性能监控
powershell
# 监控容器资源使用
docker stats
# 查看容器详细信息
docker inspect ai-mini-backend:latest
# 分析镜像大小
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
9. 最佳实践
9.1 安全最佳实践
- 使用非 root 用户运行容器
- 定期更新基础镜像
- 扫描镜像安全漏洞
- 使用多阶段构建减少攻击面
- 不在镜像中包含敏感信息
9.2 性能最佳实践
- 优化 Dockerfile 层缓存
- 使用 .dockerignore 减少构建上下文
- 选择合适的基础镜像
- 合并 RUN 指令减少层数
- 使用多阶段构建减少镜像大小
9.3 维护最佳实践
- 使用语义化版本控制
- 维护详细的变更日志
- 自动化构建和部署流程
- 定期清理旧版本镜像
- 监控镜像使用情况
10. 参考资源
文档版本 : v1.0 最后更新 : 2024年1月 维护者: AI Mini 开发团队