背景简介
配置 Python 后端项目 CI/CD 无审批环节的标准化部署。
前置信息
- Python 项目已就绪 【Python - FastAPI - 添加 health 接口模块】
- Gitea 已部署 【Gitea - Docker Compose 环境搭建】
详细信息
文件架构
backend/
|-- app/ # 应用主目录
| |-- main.py
|-- tests/ # 单元测试目录
| |-- test_health.py
|-- .gitea/
| |-- workflows/
| | |-- backend.yml # 目前是空文件
|-- ci/
| |-- backend-deploy.sh # 目前是空文件
|-- requirements.txt
|-- Dockerfile #目前是空文件
|-- pyproject.toml #目前是空文件
|-- pytest.ini
|-- docker-compose.yml #目前是空文件
准备配置文件
.gitea/workflows/backend.yml
name: Backend CI/CD Pipeline
on:
push:
branches:
- "dev/testing"
jobs:
deploy-dev:
name: Deploy Backend (Dev)
runs-on: dev-docker # gitea-act-runner配置的label
env:
ENVIRONMENT: dev
SECRET_KEY: ${{ secrets.SECRET_KEY }} # gitea 配置的 secret 名称
DATABASE_URL: ${{ secrets.DATABASE_URL }}
REDIS_URL: ${{ secrets.REDIS_URL }}
JWT_ALGORITHM: ${{ secrets.JWT_ALGORITHM }}
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Verify Python Version (可选,但推荐)
run: python --version # 这会输出 Python 3.11.x,用于确认环境正确
- name: Install Dependencies
run: |
pip install -r requirements.txt
- name: Generate .env File
run: |
echo "ENVIRONMENT=dev" > .env
echo "SECRET_KEY=${SECRET_KEY}" >> .env
echo "DATABASE_URL=${DATABASE_URL}" >> .env
echo "REDIS_URL=${REDIS_URL}" >> .env
echo "JWT_ALGORITHM=${JWT_ALGORITHM}" >> .env
echo ".env.dev file created."
- name: Run Unit Tests
run: |
pytest
- name: Deploy to Dev Environment
run: |
bash ci/backend-deploy.sh
ci/backend-deploy.sh
#!/bin/bash
set -e
# 检查 .env 是否存在
if [ ! -f ".env" ]; then
echo ".env not found!"
exit 1
fi
echo "==============================="
echo "Starting deployment..."
echo "==============================="
docker compose -f docker-compose.yml down --remove-orphans
docker compose -f docker-compose.yml up -d --build
echo "Deployment completed successfully."
添加可执行权限
chmod +x ci/backend-deploy.sh
Dockerfile
FROM python:3.11-slim
WORKDIR /backend
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENV PYTHONUNBUFFERED=1
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
docker-compse.yml
services:
pers-backend:
build: .
container_name: pers-backend
restart: always
env_file: .env
ports:
- "8000:8000"
部署 gitea act_runner
【Gitea - Docker 部署 act_runner】
注意:
- runner labe 需要修改为:
dev-docker以匹配.gitea/workflows/backend.yml的配置。- act_runner 容器需包含,需自定义部署。【Gitea - Issue - CICD - actions/checkout@v3 Cannot find: node in PATH 】
- Nodejs
- Python + pip
- Git
- Docker
创建 secret
根据各自需求添加所有环境变量
验证部署
- 提交最新的 Python 代码至
dev/testing分支 【Git - Branch 开发】
git push origin dev/testing
总共 0(差异 0),复用 0(差异 0),包复用 0
remote:
remote: Create a new pull request for 'dev/testing':
remote: https://gitea.persys.top/henrylin/pers-website-backend/compare/master...dev/testing
remote:
remote: . Processing 1 references
remote: Processed 1 references in total
To https://gitea.persys.top/henrylin/pers-website-backend.git
* [new branch] dev/testing -> dev/testing
- 查看 gitea actions 信息

【Gitea - Issue - CICD - actions/checkout@v3 Cannot find: node in PATH】
修复了部分问题后,自动化部署成功截图如下

- 部署完成后查看容器状态
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3b6bb214e261 hostexecutor-pers-backend "uvicorn app.main:ap…" About a minute ago Up About a minute 0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp pers-backend
cd47fde7cbc5 repo.docker.persys.top/pers/gitea/act_runner:python3d11d13_nodejs18_docker "/data/scripts/entry…" 6 minutes ago Up 5 minutes gitea-act-runner
- 部署完成后查看站点状态


- 查看容器log
docker logs --tail 10 pers-backend
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 172.23.0.1:39100 - "GET / HTTP/1.1" 404 Not Found
INFO: 172.23.0.1:39106 - "GET /favicon.ico HTTP/1.1" 404 Not Found
INFO: 172.23.0.1:39120 - "GET /docs HTTP/1.1" 200 OK
INFO: 172.23.0.1:39120 - "GET /openapi.json HTTP/1.1" 200 OK
INFO: 172.23.0.1:46796 - "GET /api/v1/health HTTP/1.1" 200 OK
INFO: 172.23.0.1:46800 - "GET /favicon.ico HTTP/1.1" 404 Not Found
以上便是本文的全部内容,感谢您的阅读,如遇到任何问题,欢迎在评论区留言讨论。