游乐游手机版
首页/编程语言/文章详情

CentOS Python持续集成怎么做

时间:2026-04-27 11:10
CentOS 上搭建 Python 持续集成 一 方案总览与选型 在 CentOS 上为 Python 项目搭建 CI CD 流水线,通常有几个主流选项:自建 Jenkins、使用 GitLab CI CD,或者采用 GitHub Actions。每种方案都有其适用场景,但核心流程万变不离其宗:拉取

CentOS 上搭建 Python 持续集成

CentOS Python持续集成怎么做

一 方案总览与选型

在 CentOS 上为 Python 项目搭建 CI/CD 流水线,通常有几个主流选项:自建 Jenkins、使用 GitLab CI/CD,或者采用 GitHub Actions。每种方案都有其适用场景,但核心流程万变不离其宗:拉取代码、准备环境、安装依赖、运行测试、通过质量门禁,最后完成打包与发布。

具体怎么选?Jenkins 以其高度的灵活性和强大的插件生态著称,尤其在 CentOS 上部署成熟,非常适合企业内网环境和需要深度定制的复杂流水线。而 GitLab CI 和 GitHub Actions 则主打声明式配置,用 YAML 文件就能搞定,上手速度快,与各自的代码托管平台无缝集成。值得注意的是,GitHub Actions 的托管 Runner 默认是 Ubuntu 环境,如果坚持要在 CentOS 上运行,就需要使用自托管的 Runner。

二 方案一 Jenkins 在 CentOS 自建

选择 Jenkins,意味着你获得了最大的控制权。下面来看看如何在 CentOS 上一步步把它跑起来。

准备环境

首先,得把基础环境搭好。Jenkins 本身依赖 Ja va 运行,所以需要先安装 Ja va 8 或 11。同时,Git 和 Python 3 也是必需品。为了环境隔离,强烈建议使用 Python 的 venv 模块。命令很简单:

sudo yum install -y ja va-1.8.0-openjdk git
python3 -m venv .venv && source .venv/bin/activate

安装与启动 Jenkins

推荐通过官方 RPM 仓库安装,这样后续管理升级都方便。依次执行以下命令:

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat/jenkins-ci.org.key
sudo yum install -y jenkins
sudo systemctl start jenkins

启动后,在浏览器访问 https://<你的服务器IP>:8080 就能看到 Jenkins 的初始化页面了。

初始化与插件

完成解锁和初始管理员账户设置后,会进入插件安装界面。安装“建议的插件”是个不错的开始。对于 Python 项目,有几个插件尤其关键:Git plugin(代码拉取)、Pipeline(定义流水线)、Python Plugin(提供 Python 相关工具)、Warnings Next Generation(收集代码检查警告)。如果需要更炫酷的测试报告,Allure 插件值得考虑。

创建任务与流水线

新建一个“Pipeline”类型的任务。在配置中,指定你的代码仓库地址和分支。更优雅的做法是,将流水线定义写在项目根目录的 Jenkinsfile 中,这样 Jenkins 只需从 SCM 读取并执行即可,实现了“流水线即代码”。

触发与 Webhook

触发构建的方式有两种。一种是让 Jenkins 定期轮询(Poll SCM)仓库,但这会有延迟。更高效的方式是配置 Webhook:在你的 GitLab 或 Gitee 仓库中,设置推送事件时,自动触发 Jenkins 项目的构建 URL(需要在 Jenkins 项目中生成一个带 Token 的 Webhook 地址)。

质量与报告

CI 的价值不仅在于自动化,更在于反馈。在 Jenkins 任务的“构建后操作”中,可以添加步骤来收集和展示报告。例如,解析 pytest 生成的 JUnit XML 格式报告,集成 pylint 的警告,或者展示 Allure 生成的精美测试报告看板。

部署示例

流水线的最后一步通常是部署。对于 Python 库或应用,可以使用 setup.py 打包:python setup.py sdist bdist_wheel。部署时,可以通过 scp 或 rsync 将打包好的 wheel 文件上传到生产服务器,然后远程执行 pip install。更复杂的场景,可以结合 SSH 编写滚动升级和回滚脚本。

三 方案二 GitLab CI 或 GitHub Actions

如果你的代码已经托管在 GitLab 或 GitHub,那么使用平台原生的 CI/CD 服务往往是更轻量、更直接的选择。

GitLab CI(仓库内 .gitlab-ci.yml)

一切配置都在项目根目录的 .gitlab-ci.yml 文件中。你需要定义 stages(例如 build, test, deploy),并为每个 stage 指定 runner 和执行脚本。Runner 可以使用官方的 python:3.x Docker 镜像,也可以使用自定义的 CentOS 镜像。测试阶段运行 pytest,质量门禁可以集成 pylintflake8。部署阶段则可以使用 scp、rsync 或 SSH 命令将产物发布到目标机器。

GitHub Actions(.github/workflows/ci.yml)

思路与 GitLab CI 类似,配置文件放在 .github/workflows/ 目录下。默认情况下,GitHub 会使用托管的 ubuntu-latest Runner 来执行你的工作流。如果必须使用 CentOS 环境,就需要在 CentOS 服务器上配置 self-hosted runner 并注册到你的仓库。流程通常包括:检出代码、设置 Python 环境、安装依赖、运行测试,最后根据条件触发部署。

适用场景

一句话总结:当你的代码托管在 GitLab 或 GitHub,并且希望快速落地 CI/CD 时,优先考虑它们原生的方案。但是,如果你的测试需要在 CentOS 上运行(例如涉及特定的系统库或 UI 测试),或者需要访问内网资源,那么配置一个自托管的 Runner 会是更稳妥的选择。

四 关键实践与常见问题

掌握了工具,还得知道怎么用好。下面这些实践要点,能帮你避开不少坑。

环境与依赖

切记,一定要在虚拟环境中运行你的项目!每次构建都使用 python -m venv .venv 创建一个干净的环境。为了加速构建,可以缓存 pip 下载的包(例如缓存 ~/.cache/pip 目录)。这样做能严格区分系统 Python 和项目 Python,避免依赖污染。

测试与质量

测试框架推荐 pytest,结构清晰插件丰富。结合 pytest-cov 可以生成代码覆盖率报告。静态代码检查(如 pylint, flake8)应该设定一个质量阈值,不达标就令构建失败,把问题扼杀在早期。如果涉及 UI 自动化,Selenium 或 Playwright 是常见选择,测试报告可以集成 Allure 来提升可读性。

触发策略

对于内网或自建平台,优先使用 Webhook 实现代码推送后实时触发。对于公网托管平台,配置在 push 或 pull request 事件时触发构建,通常就足够了。在一些特殊场景下,可以保留定时轮询作为兜底机制。

报告与可视化

无论是 Jenkins 还是 GitLab CI,都要善用报告可视化功能。集成 JUnit XML 报告来追踪测试通过率,收集代码检查警告来分析质量趋势,使用 Allure 报告来直观展示测试用例详情。这些是构建质量看板的基础。

安全与网络

安全无小事。用于部署的 SSH 私钥必须妥善管理,放在 Jenkins 的 Credentials 或 GitLab 的 CI/CD Variables 中,切勿硬编码在脚本里。配置 Webhook 时,要确保 GitLab 服务器能访问到 Jenkins 的回调地址(涉及内网穿透或防火墙规则)。遵循最小权限原则,为 Runner 和部署账号配置刚好够用的权限。

资源与性能

Jenkins 作为常驻服务,内存占用不低,建议服务器至少配备 1GB 内存。对于大型项目,合理设置 Jenkins 的并发构建数,并在测试时使用像 pytest-xdist 这样的插件进行测试分片,可以显著提升流水线执行速度。

五 最小可用示例

理论说了这么多,来看两个“开箱即用”的配置示例。

Jenkinsfile(声明式流水线)

这个示例展示了一个完整的声明式流水线:拉取代码、准备 Python 虚拟环境、安装依赖、运行测试与质量检查、打包,并且仅在 main 分支执行部署。

pipeline {
    agent any
    environment {
        PYTHON = 'python3'
        VENV= '.venv'
    }
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'git@your-gitlab.com:group/project.git'
            }
        }
        stage('Setup') {
            steps {
                sh '''
                    ${PYTHON} -m venv ${VENV}
                    . ${VENV}/bin/activate
                    pip install --upgrade pip
                    pip install -r requirements.txt
                '''
            }
        }
        stage('Test & Quality') {
            steps {
                sh '''
                    . ${VENV}/bin/activate
                    pytest --junitxml=reports/pytest.xml --maxfail=1
                    pylint --output-format=parseable src/ || true
                '''
            }
            post {
                always {
                    junit 'reports/pytest.xml'
                    warnings canComputeNew: false, defaultEncoding: '', excludePattern: '', healthy: '', includePattern: '**/pylint*.xml', messagesPattern: '', parserConfigurations: [[parserName: 'PyLint', pattern: '**/pylint*.xml']], unHealthy: ''
                }
            }
        }
        stage('Package') {
            steps {
                sh '''
                    . ${VENV}/bin/activate
                    python setup.py sdist bdist_wheel
                '''
            }
        }
        stage('Deploy') {
            when { branch 'main' }
            steps {
                sh '''
                    . ${VENV}/bin/activate
                    pip install scp
                    python - <<'PY'
import os, scp, paramiko
src=os.path.expanduser("dist/*.whl")
dst="/opt/pkgs/"
key=paramiko.RSAKey.from_private_key_file("/var/lib/jenkins/.ssh/id_rsa")
with paramiko.SSHClient() as c:
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    c.connect("prod.example.com", username="deploy", pkey=key)
    with scp.SCPClient(c.get_transport()) as s:
        s.put(src, dst)
PY
                    ssh deploy@prod.example.com "pip install /opt/pkgs/*.whl && systemctl restart myapp"
                '''
            }
        }
    }
}

.gitlab-ci.yml(GitLab CI 示例)

这是一个对应的 GitLab CI 配置示例,使用官方 Python 镜像,同样包含构建、测试、部署三个阶段,并且部署仅针对 main 分支。

stages:
  - build
  - test
  - deploy

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"

cache:
  paths:
    - .cache/pip
    - .venv

build:
  stage: build
  image: python:3.11
  script:
    - python -m venv .venv
    - . .venv/bin/activate
    - pip install --upgrade pip
    - pip install -r requirements.txt
    - python setup.py sdist bdist_wheel

test:
  stage: test
  image: python:3.11
  script:
    - . .venv/bin/activate
    - pytest --junitxml=reports/pytest.xml --maxfail=1
    - pylint --output-format=parseable src/ || true
  artifacts:
    when: always
    reports:
      junit: reports/pytest.xml

deploy:
  stage: deploy
  image: python:3.11
  script:
    - . .venv/bin/activate
    - pip install scp
    - python - <<'PY'
import os, scp, paramiko
src=os.path.expanduser("dist/*.whl")
dst="/opt/pkgs/"
key=paramiko.RSAKey.from_private_key_file("/builds/.ssh/id_rsa")
with paramiko.SSHClient() as c:
    c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    c.connect("prod.example.com", username="deploy", pkey=key)
    with scp.SCPClient(c.get_transport()) as s:
        s.put(src, dst)
PY
    - ssh deploy@prod.example.com "pip install /opt/pkgs/*.whl && systemctl restart myapp"
  only:
    - main
来源:https://www.yisu.com/ask/99048003.html
上一篇如何定制CentOS Golang日志输出 下一篇CentOS Python机器学习框架怎么用
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
如何在ThinkPHP中实现定时任务与命令行调度方法
编程语言 · 2026-07-04

如何在ThinkPHP中实现定时任务与命令行调度方法

用ThinkPHP实现定时任务时,很多开发者第一步就卡在命令行报错上,直接输入php think your:command却无法识别——这种情况绝大多数是因为命令类的注册方式存在问题。下面先梳理几个核心要点。 ThinkPHP 6 中 think 命令如何正确触发自定义指令 直接运行 php thi

ThinkPHP API接口防重放攻击实现方法
编程语言 · 2026-07-04

ThinkPHP API接口防重放攻击实现方法

先说几个核心判断:API防重放攻击这件事,做对了是道防火墙,做错了就是个心理安慰。很多开发者到踩坑了才明白——验签这东西,放错位置、漏掉字段、存错nonce,每一环都能让整个安全体系直接归零。 验签必须放在中间件里,不能在控制器里写 ThinkPHP 的请求生命周期中,中间件是唯一能在路由匹配、参数

ThinkPHP文件上传必须验证扩展名安全必要性分析
编程语言 · 2026-07-04

ThinkPHP文件上传必须验证扩展名安全必要性分析

在使用ThinkPHP进行文件上传时,ext扩展名验证通常是开发者首先接触的关键环节。但你真的了解它的实际工作原理吗?它仅比对文件名后缀,而不读取文件内容,甚至对空格和大小写都极其敏感。更为重要的是——它是TP文件上传验证五层防线中不可忽视的第一道关卡,一旦配置遗漏,整个validate验证链将直接

ThinkPHP关联模型自动写入与更新使用教程
编程语言 · 2026-07-04

ThinkPHP关联模型自动写入与更新使用教程

需要明确的是,ThinkPHP关联模型并没有提供所谓的“自动写入 更新”魔法开关。所谓的“自动”功能,实际上都需要开发者手动编写配置逻辑才能生效。核心原则在于:主模型和从模型必须分开独立处理,时间戳字段和业务字段需依靠修改器或钩子接管;批量操作则要规规矩矩地绕过模型逻辑来执行——只有理解透彻这些要点

BoxLayout中仅居中一个组件其他默认左对齐
编程语言 · 2026-07-04

BoxLayout中仅居中一个组件其他默认左对齐

在 Java Swing 中使用 BoxLayout 的 Y_AXIS 方向布局时,很多初学者容易掉进一个常见陷阱:希望将某个组件单独设置为中心对齐,但当调用 `setAlignmentX(CENTER_ALIGNMENT)` 后,却发现其他组件也跟着发生了偏移,完全达不到预期效果。实际上,关键之处