Files
photography/.gitea/workflows/deploy-backend.yml
xujiang 7ea3d8142b
Some checks failed
部署后端服务 / 🚀 构建并部署 (push) Failing after 6m40s
部署后端服务 / 🔄 回滚部署 (push) Failing after 2s
fix: 修复阿里云容器镜像仓库认证失败问题
- 增加 Docker 登录验证步骤
- 添加构建重试机制
- 优化认证流程稳定性
- 增强错误处理和日志输出

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-15 13:46:20 +08:00

256 lines
9.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: 部署后端服务
on:
push:
branches: [ main ]
paths:
- 'backend/**'
- '.env.example'
- '.gitea/workflows/deploy-backend.yml'
workflow_dispatch:
env:
REGISTRY: crpi-b4fqtfbvv583enk2.cn-shanghai.personal.cr.aliyuncs.com
IMAGE_NAME: photography-backend/photography
jobs:
build-and-deploy:
name: 🚀 构建并部署
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: 📥 检出代码
uses: actions/checkout@v4
- name: 🐳 设置 Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
network=host
- name: 🔧 配置 Docker 镜像代理
run: |
# 创建 Docker daemon 配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<EOF
{
"registry-mirrors": [
"https://docker.1ms.run",
"https://hub.skillixx.com/"
]
}
EOF
# 重启 Docker 服务
sudo systemctl restart docker || true
# 验证配置
docker info | grep -A 5 "Registry Mirrors" || true
- name: 🔑 登录到镜像仓库
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
env:
DOCKER_CLI_EXPERIMENTAL: enabled
- name: 🔍 验证镜像仓库连接
run: |
echo "🔍 验证镜像仓库连接..."
docker pull hello-world:latest || true
docker logout ${{ env.REGISTRY }} || true
echo "🏷️ 重新登录镜像仓库..."
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login ${{ env.REGISTRY }} --username "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: 📝 提取元数据
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: 🏗️ 构建并推送镜像
uses: docker/build-push-action@v5
with:
context: ./backend
file: ./backend/Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
provenance: false
sbom: false
continue-on-error: true
id: build_push
- name: 🔄 重试构建和推送
if: steps.build_push.outcome == 'failure'
run: |
echo "⚠️ 构建推送失败等待10秒后重试..."
sleep 10
docker buildx build --push \
--platform linux/amd64 \
--tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} \
--tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
--cache-from type=gha \
--cache-to type=gha,mode=max \
--provenance=false \
--sbom=false \
./backend
- name: 📦 同步配置文件
run: |
# 安装sshpass用于密码认证
sudo apt-get update && sudo apt-get install -y sshpass
# 同步配置文件到服务器
echo "📋 同步配置文件到服务器..."
export SSHPASS=${{ secrets.TYY_PWD }}
sshpass -e scp -o StrictHostKeyChecking=no -P ${{ secrets.PORT }} backend/docker-compose.prod.yml ${{ secrets.TYY_USER }}@${{ secrets.HOST }}:/data/docker/photography/backend/docker-compose.yml
# 创建生产环境配置文件
echo "📋 创建生产环境配置..."
sed -e "s/DB_USER=.*/DB_USER=${{ secrets.POSTGRES_PHOTO_USER }}/" \
-e "s/DB_PASSWORD=.*/DB_PASSWORD=${{ secrets.POSTGRES_PHOTO_PWD }}/" \
-e "s/DB_HOST=.*/DB_HOST=localhost/" \
-e "s/APP_ENV=.*/APP_ENV=production/" \
backend/.env.example > /tmp/production.env
sshpass -e scp -o StrictHostKeyChecking=no -P ${{ secrets.PORT }} /tmp/production.env ${{ secrets.TYY_USER }}@${{ secrets.HOST }}:/data/docker/photography/backend/.env
echo "✅ 配置文件同步完成"
- name: 🚀 部署到生产环境
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.TYY_USER }}
password: ${{ secrets.TYY_PWD }}
port: ${{ secrets.PORT }}
script: |
# 切换到后端项目目录
cd /data/docker/photography/backend
# 备份当前运行的容器 (如果存在)
if docker ps -q -f name=photography-api; then
echo "📦 备份当前后端容器..."
docker commit photography-api photography_backend_backup_$(date +%Y%m%d_%H%M%S)
fi
# 停止现有服务
echo "🛑 停止现有服务..."
docker-compose down api || true
# 拉取最新镜像
echo "📥 拉取最新镜像..."
docker-compose pull api
# 数据库迁移需要手动执行
echo "⚠️ 数据库迁移需要手动执行,请在部署后运行:"
echo " docker-compose exec api ./main migrate"
# 启动后端服务
echo "🚀 启动后端服务..."
docker-compose up -d api
# 等待服务启动
echo "⏳ 等待服务启动..."
sleep 30
# 健康检查
echo "🔍 执行健康检查..."
for i in {1..30}; do
if curl -f http://localhost:8080/health > /dev/null 2>&1; then
echo "✅ 后端服务健康检查通过"
break
fi
echo "等待后端服务启动... ($i/30)"
sleep 10
done
# 检查服务状态
echo "📊 检查服务状态..."
docker-compose ps
# 清理旧镜像 (保留最近3个)
echo "🧹 清理旧镜像..."
docker images ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}" | tail -n +2 | sort -k2 -r | tail -n +4 | awk '{print $1}' | xargs -r docker rmi || true
# 清理旧备份容器 (保留最近5个)
docker images photography_backend_backup_* --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}" | tail -n +2 | sort -k2 -r | tail -n +6 | awk '{print $1}' | xargs -r docker rmi || true
echo "🎉 后端部署完成!"
echo "📋 请记住手动运行数据库迁移:"
echo " docker-compose exec api ./main migrate"
- name: 📧 发送部署通知
if: always()
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_TO }}
token: ${{ secrets.TELEGRAM_TOKEN }}
message: |
🔧 摄影作品集后端部署
📦 项目: ${{ github.repository }}
🌿 分支: ${{ github.ref_name }}
👤 提交者: ${{ github.actor }}
📝 提交信息: ${{ github.event.head_commit.message }}
${{ job.status == 'success' && '✅ 部署成功' || '❌ 部署失败' }}
${{ job.status == 'success' && '⚠️ 请记住手动运行数据库迁移: docker-compose exec api ./main migrate' || '' }}
🌐 API: https://api.photography.iriver.top/health
📊 监控: https://admin.photography.iriver.top
rollback:
name: 🔄 回滚部署
runs-on: ubuntu-latest
if: failure() && github.ref == 'refs/heads/main'
needs: build-and-deploy
steps:
- name: 🔄 执行回滚
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.TYY_USER }}
password: ${{ secrets.TYY_PWD }}
port: ${{ secrets.PORT }}
script: |
cd /data/docker/photography/backend
echo "🔄 开始回滚后端服务..."
# 查找最新的备份容器
BACKUP_IMAGE=$(docker images photography_backend_backup_* --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}" | tail -n +2 | sort -k2 -r | head -n 1 | awk '{print $1}')
if [ -n "$BACKUP_IMAGE" ]; then
echo "📦 找到备份镜像: $BACKUP_IMAGE"
# 停止当前服务
docker-compose down backend
# 标记备份镜像为最新
docker tag $BACKUP_IMAGE photography_backend:rollback
# 修改 docker-compose 使用回滚镜像
sed -i 's|build: .*|image: photography_backend:rollback|g' docker-compose.yml
# 启动回滚版本
docker-compose up -d backend
echo "✅ 回滚完成"
else
echo "❌ 未找到备份镜像,无法回滚"
exit 1
fi