Conda+Git+Docker+Jenkins+TypeScript+Playwright 构建 CI/CD + 自动化测试完整流程
本次方案在原有Git+Docker+Jenkins+TS+Playwright基础上融入Conda,核心解决Python 环境隔离与依赖管理问题(适配 TS/Playwright 主工程中嵌入 Python 模块、多版本 Python 依赖、Python 侧辅助脚本 / 服务等场景),全程保持容器化统一环境核心设计,实现「代码提交→环境构建→TS 编译→自动化测试→镜像打包→容器部署」的端到端 CI/CD 流水线,同时保证 Python/Conda、Node.js/TS 两大环境互不冲突、独立隔离。
一、技术栈说明(核心作用 + 版本建议 + 协同关系)
各技术栈分工明确,Conda 作为 Python 专属环境管理工具,不替代 Node.js(TS/Playwright 的基础),二者在容器内协同运行,Docker 实现全环境容器化,Jenkins 负责流水线编排,形成「版本管理 + 双环境隔离 + 容器化 + 流水线 + 自动化测试」的完整体系:
技术栈 | 核心作用 | 版本建议 | 协同关系 |
Git | 代码版本管理、分支控制、Jenkins 构建触发(WebHook)
| GitLab/GitHub/Gitee | 托管所有代码 + 配置文件(含 Conda/TS/ 流水线配置) |
Conda(Miniconda3) | Python 环境隔离、Python 依赖安装 / 版本管理,支持多 Python 环境切换 | Miniconda3-py310_23.10.0 | 与 Node.js 共存于容器,仅管理 Python 侧依赖 |
Docker | 全环境容器化打包(Conda+Node.js + 应用 + 测试),解决环境不一致问题 | 24.0+ | 作为所有环节的统一运行载体,包含 Conda/Node.js 基础环境 |
Docker Compose | 编排多容器服务(Jenkins+Docker-daemon、带 Conda 的应用容器) | 2.24+ | 简化 Jenkins 和应用容器的部署与管理 |
Jenkins | CI/CD 流水线核心编排,串联所有环节,将自动化测试作为强制卡点 | 2.450+(LTS) | 无需内置 Conda/Node.js,通过 Docker 调用容器内环境 |
TypeScript | 主工程开发语言(前端 Vue/React、后端 Node.js/Express),强类型保证代码质量 | 5.2+ | 基于 Node.js 运行,与 Conda 环境完全隔离 |
Playwright | 自动化测试框架,支持多浏览器 E2E 测试 / 接口测试,TS 原生支持,可测试 Python/TS 混合服务 | 1.40+ | 基于 Node.js 运行,可调用 Conda 管理的 Python 服务接口 |
Node.js | TS 编译运行、Playwright 执行的基础,提供 npm/yarn 包管理 | 18.x/20.x(LTS) | 与 Conda 共存于容器,通过环境变量隔离 |
Python | 工程辅助模块开发(如数据处理、接口代理、自动化脚本) | 3.9+/3.10+ | 由 Conda 统一管理版本和依赖 |
核心设计思路
- 双环境隔离共存:Conda 管理 Python 环境(含版本、依赖),Node.js 管理 TS/Playwright 环境,二者在同一 Docker 镜像中通过环境变量隔离,互不干扰;
- 容器化贯穿全程:Jenkins、Conda+Node.js 运行环境、目标应用、Playwright 测试均基于 Docker 运行,彻底消除「本地能跑、远端失败」的环境问题;
- Conda 配置代码化:通过environment.yml定义 Conda 环境(Python 版本、依赖),实现「Python 环境即代码」,与项目代码一起托管到 Git;
- 测试强制卡点:Playwright 自动化测试覆盖 TS 主服务和 Conda 管理的 Python 辅助服务,测试不通过则终止流水线,禁止镜像构建和部署;
- Jenkins 轻量编排:Jenkins 本身不安装 Conda/Node.js,仅通过 Docker 命令调用项目专属镜像中的环境,简化 Jenkins 配置,提升流水线可移植性。
二、环境前置配置(服务器端,核心:Docker+Jenkins + 基础权限)
前提条件
- 一台 Linux 服务器(Ubuntu 20.04/22.04 推荐,内存≥4G、硬盘≥50G,因新增 Conda 环境,需略增加磁盘空间);
- 本地开发机安装:Git、Miniconda3、Node.js、Docker、VSCode(TS/Python 开发);
- 服务器端仅需提前安装 Docker+Docker Compose,Conda/Node.js 无需服务器手动安装,全部在项目 Docker 镜像中构建。
步骤 1:服务器端安装 Docker+Docker Compose(基础)
与原有方案一致,核心是配置 Docker 免 sudo,避免后续 Jenkins 操作 Docker 权限问题,执行以下命令:
# 1. 卸载旧版本(如有)sudo apt-get remove docker docker-engine docker.io containerd runc# 2. 安装依赖sudo apt-get update && sudo apt-get install -y ca-certificates curl gnupg lsb-release# 3. 添加Docker官方GPG密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg# 4. 添加Docker软件源echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null# 5. 安装Docker Engine+Containerd+Docker Composesudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin# 6. 验证安装docker --version && docker compose version# 7. 配置免sudo(核心,避免Jenkins操作Docker权限错误)sudo usermod -aG docker $USERnewgrp docker # 权限立即生效,无需重启步骤 2:Docker 化部署 Jenkins(带 Docker 权限挂载,无修改)
Jenkins 仍采用容器化部署,核心是挂载宿主机 Docker 套接字,让 Jenkins 容器能执行docker build/push/run命令,无需内置 Conda/Node.js,配置与原有方案一致,保证轻量性。
2.1 新建 Jenkins 持久化目录
mkdir -p ~/jenkins/{home,workspace}sudo chmod -R 777 ~/jenkins # 赋予读写权限,避免容器操作失败2.2 编写 Jenkins 专属 docker-compose.yml
在~/jenkins目录下创建docker-compose.yml:
version: '3.8'services: jenkins: image: jenkins/jenkins:lts-jdk17 # 基于JDK17,兼容后续所有操作 container_name: jenkins-ci-cd restart: always ports: - "8080:8080" # Jenkins前端访问端口 - "50000:50000" # Jenkins代理节点通信端口 volumes: - ~/jenkins/home:/var/jenkins_home # 持久化Jenkins配置/插件 - ~/jenkins/workspace:/var/jenkins_workspace # 流水线工作空间 - /var/run/docker.sock:/var/run/docker.sock # 核心:挂载Docker套接字 - /usr/bin/docker:/usr/bin/docker # 挂载Docker命令行工具 - /usr/libexec/docker/cli-plugins:/usr/libexec/docker/cli-plugins # 挂载Docker Compose插件 environment: - TZ=Asia/Shanghai # 配置时区,避免构建时间错乱2.3 启动 Jenkins 并完成初始化
cd ~/jenkinsdocker compose up -d# 查看启动日志,获取初始化密码docker logs -f jenkins-ci-cd浏览器访问http://服务器IP:8080,按提示完成初始化:输入日志中的初始化密码→安装推荐插件→创建管理员账户→确认访问地址,步骤与原有方案一致,无额外配置。
步骤 3:Jenkins 安装必备插件(无新增,保留原有)
因 Conda/Node.js 环境在项目 Docker 镜像中管理,Jenkins 无需新增插件,仅保留原有核心插件即可,安装完成后重启 Jenkins:
- 登录 Jenkins → 系统管理 → 插件管理 → 可选插件;
- 搜索并安装以下插件(勾选后直接安装): Git Plugin(Git 代码拉取) NodeJS Plugin(备用,若需 Jenkins 直接调用 Node.js) Docker Plugin(Docker 管理) Docker Pipeline Plugin(Pipeline 执行 Docker 命令) Pipeline Plugin(声明式流水线基础) HTML Publisher Plugin(Playwright 测试报告归档) Generic Webhook Trigger Plugin(Git WebHook 触发,可选)
- 重启 Jenkins:docker restart jenkins-ci-cd。
步骤 4:Jenkins 全局工具配置(极简,仅保留 Git)
核心变化:无需在 Jenkins 中配置 Node.js/Conda,所有环境均在项目 Docker 镜像中构建,Jenkins 仅需识别 Git 即可,简化配置:
- 登录 Jenkins → 系统管理 → 全局工具配置;
- Git 配置:填写名称(如Git-2.39),路径留空(容器内已内置 Git);
- 无需配置 Node.js/Conda,直接点击「保存」。
三、核心实施步骤(从本地开发到 Jenkins 流水线,核心融合 Conda)
整体流程概览
本地开发(Conda+TS+Playwright)→ 编写Conda/TS/测试配置 → Git提交代码到远程仓库 → Jenkins(手动/WebHook)触发构建 → 流水线执行(拉取代码→Docker构建(含Conda+Node.js环境)→ 启动容器内服务 → Playwright自动化测试 → 重新打包生产镜像 → 部署容器)→ 测试报告归档/构建结果通知核心变化:将「Conda 环境创建、Node.js 依赖安装、TS 编译」全部移入Docker 构建阶段,Jenkins 流水线仅负责调用 Docker 命令,大幅简化流水线逻辑,提升环境一致性。
步骤 1:本地开发环境初始化(Conda+TS+Playwright)
本地需同时配置 CondaPython 环境和 Node.jsTS 环境,先完成本地验证,再提交代码,避免远端流水线失败。
1.1 本地创建项目目录并初始化 Conda 环境
Conda 环境通过environment.yml配置,实现代码化管理,替代手动conda create/install命令,方便 Git 托管和远端构建。
# 1. 创建项目根目录mkdir conda-ts-playwright-ci-cd && cd conda-ts-playwright-ci-cd# 2. 编写Conda环境配置文件environment.yml(核心)touch environment.yml# 3. 初始化Conda环境(本地测试用)conda env create -f environment.yml# 4. 激活Conda环境conda activate ts-py-env # 环境名与environment.yml中一致关键:environment.yml 配置文件(Python 版本 + 依赖)
定义 Conda 环境名称、Python 版本、需要安装的 Python 依赖(如requests/flask/pandas等,根据项目需求调整),示例:
name: ts-py-env # Conda环境名称,本地和远端一致channels: # Conda镜像源,提升下载速度 - defaults - conda-forgedependencies: # 依赖列表,版本可指定 - python=3.10 # Python版本,建议3.9+ - pip=24.0 # pip版本 - flask=2.3.3 # 示例:Python Web框架(若有Python辅助服务) - requests=2.31.0 # 示例:Python请求库 - pip: # 额外pip安装的依赖(可选) - pyyaml==6.0.11.2 本地初始化 TS+Playwright 项目
与原有方案一致,安装 TS 核心依赖和 Playwright,编写业务代码和测试用例,注意:Node.js 环境与 Conda 环境完全隔离,无需激活 Conda 即可运行。
# 1. 初始化npm项目npm init -y# 2. 安装TS开发依赖npm i -D typescript @types/node ts-node @types/express# 3. 初始化TS配置文件npx tsc --init# 4. 安装Playwright并初始化测试环境npm i -D @playwright/testnpx playwright install --with-deps # 安装浏览器和依赖npx playwright init # 生成tests目录和playwright.config.ts# 5. 安装TS业务依赖(示例:Express)npm i express1.3 调整 tsconfig.json(适配 Node.js,无修改)
修改核心配置,编译 TS 到dist目录,示例:
{ "compilerOptions": { "target": "ES2020", "module": "CommonJS", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true }, "include": ["./src/**/*"], "exclude": ["./node_modules", "./tests", "./playwright-report", "./conda-env"]}1.4 编写混合业务代码(TS 主服务 + Python 辅助服务,示例)
适配「TS 为主、Python 为辅」的典型场景,编写简单服务代码,用于后续自动化测试:
- TS 主服务(src/index.ts):Node.js/Express 接口
- typescript
- 运行
- import express, { Request, Response } from 'express'; const app = express(); const TS_PORT = 3000; // TS核心接口 app.get('/ts/api', (req: Request, res: Response) => { res.send({ code: 200, type: 'ts', msg: 'TS主服务正常运行', data: { title: 'Conda+TS CI/CD Demo' } }); }); app.listen(TS_PORT, () => { console.log(`TS服务运行在:http://localhost:${TS_PORT}`); }); export default app;
- Python 辅助服务(py/app.py):Flask 接口(由 Conda 管理)
- python
- 运行
- from flask import Flask import os app = Flask(__name__) PY_PORT = 5000 # Python辅助接口 @app.route('/py/api') def py_api(): return { "code": 200, "type": "python", "msg": "Python辅助服务正常运行(Conda管理)", "conda_env": os.environ.get('CONDA_DEFAULT_ENV', 'ts-py-env') } if __name__ == '__main__': app.run(host='0.0.0.0', port=PY_PORT, debug=False)
1.5 编写 Playwright 自动化测试用例(覆盖 TS+Python 服务)
在tests目录下创建mixed.spec.ts,测试TS 主服务和 Python 辅助服务的可用性,实现全链路测试:
import { test, expect } from '@playwright/test';test('全链路测试:TS服务+Python辅助服务', async ({ request }) => { // 测试TS主服务接口 const tsResponse = await request.get('http://localhost:3000/ts/api'); expect(tsResponse.status()).toBe(200); const tsData = await tsResponse.json(); expect(tsData.code).toBe(200); expect(tsData.type).toBe('ts'); // 测试Python辅助服务接口(Conda管理) const pyResponse = await request.get('http://localhost:5000/py/api'); expect(pyResponse.status()).toBe(200); const pyData = await pyResponse.json(); expect(pyData.code).toBe(200); expect(pyData.type).toBe('python'); expect(pyData.conda_env).toBe('ts-py-env'); // 验证Conda环境激活成功});1.6 配置 package.json 脚本(本地开发 / 测试)
封装 TS 编译、服务启动、测试命令,本地验证使用:
{ "scripts": { "dev:ts": "ts-node src/index.ts", // 启动TS服务 "build": "tsc", // 编译TS到dist目录 "start:ts": "node dist/index.js", // 运行TS生产服务 "test": "playwright test", // 执行Playwright测试 "test:report": "playwright show-report" // 查看测试报告 }}1.7 本地全流程验证(必做)
本地同时启动 TS 服务和 Python 服务,执行 Playwright 测试,验证所有环节正常:
# 1. 激活Conda环境,启动Python服务(后台运行)conda activate ts-py-envpython py/app.py > py-service.log 2>&1 2. 编译TS代码,启动TS服务(后台运行)npm run buildnpm run start:ts > ts-service.log 2>&1 3. 等待服务就绪,执行Playwright测试sleep 5 && npm run test# 4. 本地查看测试报告npm run test:report验证通过标准:Conda 环境激活正常、Python/TS 服务均启动、Playwright 测试用例 100% 通过、生成playwright-reportHTML 报告。
步骤 2:Git 仓库配置(新增 Conda 相关忽略文件)
编写.gitignore,排除 Conda 环境、Node.js 依赖、编译产物等无用文件,减少仓库体积:
# Conda环境相关(本地环境,不提交)conda-env/env/.conda/conda-meta/pkgs/*.conda# Node.js依赖node_modules/# TS编译产物dist/# Playwright测试相关playwright-report/test-results/playwright/.cache/# 环境变量和配置.env.env.*.DS_Store# IDE配置.idea/.vscode/*.swp# Docker相关.dockerignore# 日志文件*.log完成后,将所有代码和配置文件提交到远程 Git 仓库(GitHub/GitLab/Gitee):
git initgit remote add origin 你的Git仓库地址git add .git commit -m "init: Conda+TS+Playwright项目,完成基础服务和自动化测试"git push -u origin main步骤 3:编写 Dockerfile(核心,融合 Conda+Node.js 环境)
这是本次方案的核心:基于Miniconda3 官方镜像构建基础环境,在同一镜像中安装 Node.js,创建 CondaPython 环境,安装 Python/Node.js 依赖,编译 TS 代码,实现「Conda+Node.js 双环境共存且隔离」,最终生成包含完整运行环境的应用镜像。
采用多阶段构建,分为「构建阶段」(包含所有开发依赖,用于编译、测试)和「运行阶段」(仅包含生产依赖,轻量),示例 Dockerfile(项目根目录):
# 阶段1:构建阶段(Conda+Node.js+开发依赖,用于编译TS和测试)FROM continuumio/miniconda3:latest AS builderLABEL maintainer="CI/CD Demo"WORKDIR /app# 步骤1:配置Conda环境,安装Python依赖COPY environment.yml .# 创建Conda环境(与本地一致),并激活RUN conda env create -f environment.yml && \ echo "conda activate ts-py-env" >> ~/.bashrc # 写入bashrc,自动激活环境# 配置Conda环境变量(核心,让容器内任意命令行可调用conda环境)ENV PATH /opt/conda/envs/ts-py-env/bin:$PATHENV CONDA_DEFAULT_ENV ts-py-env# 步骤2:安装Node.js(LTS 20.x,与本地一致)RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \ apt-get update && apt-get install -y nodejs && \ node -v && npm -v # 验证Node.js安装# 步骤3:复制Node.js依赖配置,安装所有依赖(含开发依赖)COPY package*.json .RUN npm ci # 比npm install更快,更严格,适配CI/CD# 步骤4:复制所有项目代码,编译TS代码COPY . .RUN npm run build # 编译TS到dist目录# 阶段2:运行阶段(仅包含生产依赖,轻量,用于最终部署)FROM continuumio/miniconda3:latest AS runnerWORKDIR /appENV PYTHONUNBUFFERED=1ENV PATH /opt/conda/envs/ts-py-env/bin:$PATHENV CONDA_DEFAULT_ENV ts-py-env# 步骤1:从构建阶段复制Conda环境(核心,避免重新安装)COPY --from=builder /opt/conda/envs/ts-py-env /opt/conda/envs/ts-py-env# 步骤2:从构建阶段复制Node.js环境COPY --from=builder /usr/bin/node /usr/bin/nodeCOPY --from=builder /usr/lib/node_modules /usr/lib/node_modulesRUN ln -s /usr/lib/node_modules/npm/bin/npm-cli.js /usr/bin/npm# 步骤3:复制TS编译产物、Python代码、生产依赖配置COPY --from=builder /app/dist ./distCOPY --from=builder /app/py ./pyCOPY --from=builder /app/package*.json .# 安装Node.js生产依赖(移除开发依赖)RUN npm ci --only=production# 步骤4:暴露端口(TS服务3000 + Python服务5000)EXPOSE 3000 5000# 步骤5:编写启动脚本(核心,同时启动TS和Python服务)COPY start.sh .RUN chmod +x start.sh # 赋予执行权限# 启动命令CMD ["./start.sh"]关键配套文件:start.sh(启动脚本,同时运行 TS+Python 服务)
因需要同时启动TS 主服务和Python 辅助服务,编写 Shell 脚本作为容器启动命令,替代手动启动,确保容器启动后所有服务正常运行:
#!/bin/bashset -e # 任意命令失败则终止脚本# 激活Conda环境source /opt/conda/bin/activate ts-py-env# 后台启动Python辅助服务echo "启动Python辅助服务(Conda管理)..."python py/app.py 前台启动TS主服务(容器主进程,保证容器不退出)echo "启动TS主服务..."node dist/index.js将start.sh放在项目根目录,与 Dockerfile 同级,确保本地赋予执行权限:chmod +x start.sh。
编写.dockerignore 文件(优化 Docker 构建)
排除 Docker 构建时无需复制的文件,提升构建速度,减少镜像体积:
# Conda相关environment.ymlconda-env/# Node.js相关node_modules/# TS相关src/tsconfig.json# 测试相关tests/playwright.config.tsplaywright/# Git相关.git/.gitignore# 其他Jenkinsfilestart.sh.bak*.log步骤 4:编写 Jenkinsfile(声明式流水线,简化版)
核心变化:流水线逻辑大幅简化,将「Conda 环境创建、Node.js 依赖安装、TS 编译」全部移入 Docker 构建阶段,Jenkins 仅负责拉取代码→构建测试镜像→运行容器→执行 Playwright 测试→构建生产镜像→部署容器,所有环境相关操作均在容器内完成,提升流水线稳定性。
Jenkinsfile(项目根目录,声明式,带详细注释):
groovy
// 声明式流水线pipeline { agent any // 运行在Jenkins本地节点 // 环境变量配置 environment { APP_NAME = "conda-ts-playwright-ci-cd" // 应用名称 TEST_IMAGE = "${APP_NAME}:test" // 测试镜像标签(含开发依赖) PROD_IMAGE = "${APP_NAME}:latest" // 生产镜像标签(轻量) CONTAINER_NAME = "${APP_NAME}-container"// 容器名称 TS_PORT = 3000 // TS服务端口 PY_PORT = 5000 // Python服务端口 } // 流水线阶段(核心) stages { // 阶段1:拉取Git仓库代码 stage('拉取代码') { steps { echo "===== 拉取Git仓库${env.GIT_URL}的${env.BRANCH_NAME}分支代码 =====" git url: "${env.GIT_URL}", branch: "${env.BRANCH_NAME}", credentialsId: '' // 私有仓库填写凭证ID } } // 阶段2:构建Docker测试镜像(含Conda+Node.js+开发依赖) stage('构建测试镜像') { steps { echo "===== 构建Docker测试镜像:${env.TEST_IMAGE} =====" sh "docker build -t ${env.TEST_IMAGE} ." // 验证镜像构建成功 sh "docker images | grep ${env.TEST_IMAGE} || (echo '测试镜像构建失败' && exit 1)" } } // 阶段3:运行测试容器+执行Playwright自动化测试(强制卡点) stage('自动化测试(Playwright)') { steps { echo "===== 启动测试容器并执行Playwright自动化测试 =====" // 停止并删除旧容器(若存在) sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true" // 启动测试容器(端口映射、后台运行,挂载项目目录用于获取测试报告) sh "docker run -d --name ${env.CONTAINER_NAME} \ -p ${env.TS_PORT}:${env.TS_PORT} -p ${env.PY_PORT}:${env.PY_PORT} \ -v \$(pwd):/app \ ${env.TEST_IMAGE} \ /bin/bash -c 'source /opt/conda/bin/activate ts-py-env && npm run test'" // 等待测试完成,查看容器日志 sh "docker logs -f ${env.CONTAINER_NAME}" // 验证测试是否通过(容器退出码为0则通过) sh "docker inspect ${env.CONTAINER_NAME} --format='{{.State.ExitCode}}' | grep 0 || (echo '自动化测试失败' && exit 1)" } post { // 无论测试成功/失败,归档Playwright测试报告 always { echo "===== 归档自动化测试报告 =====" publishHTML( target: [ allowMissing: false, alwaysLinkToLastBuild: true, reportDir: 'playwright-report', reportFiles: 'index.html', reportName: 'Conda+TS Playwright自动化测试报告' ] ) // 清理测试容器 sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true" } // 测试失败,终止流水线 failure { error "===== 自动化测试用例执行失败,禁止构建生产镜像和部署 =====" } } } // 阶段4:构建Docker生产镜像(轻量,仅含生产依赖) stage('构建生产镜像') { steps { echo "===== 构建Docker生产镜像:${env.PROD_IMAGE} =====" sh "docker build -t ${env.PROD_IMAGE} --target runner ." // 指定运行阶段 // 验证生产镜像构建成功 sh "docker images | grep ${env.PROD_IMAGE} || (echo '生产镜像构建失败' && exit 1)" } } // 阶段5:部署生产容器(最终部署) stage('部署生产容器') { steps { echo "===== 部署生产容器:${env.CONTAINER_NAME} =====" // 停止并删除旧生产容器(若存在) sh "docker stop ${env.CONTAINER_NAME} || true && docker rm ${env.CONTAINER_NAME} || true" // 启动生产容器(后台运行、自动重启、端口映射) sh "docker run -d --name ${env.CONTAINER_NAME} \ -p ${env.TS_PORT}:${env.TS_PORT} -p ${env.PY_PORT}:${env.PY_PORT} \ --restart always \ ${env.PROD_IMAGE}" // 验证容器启动成功 sh "docker ps | grep ${env.CONTAINER_NAME} || (echo '生产容器启动失败' && docker logs ${env.CONTAINER_NAME} && exit 1)" echo "===== 部署成功!TS服务:http://${env.JENKINS_URL%:*}:${env.TS_PORT}/ts/api | Python服务:http://${env.JENKINS_URL%:*}:${env.PY_PORT}/py/api =====" } } } // 流水线后置操作 post { success { echo "===== 流水线执行成功!✅ Conda+TS+Playwright应用已完成构建、测试、部署 =====" } failure { echo "===== 流水线执行失败!❌ 请查看控制台日志和测试报告排查问题 =====" } always { // 清理工作空间,避免磁盘占用 cleanWs() } }}步骤 5:Jenkins 创建 Pipeline 任务(关联 Git+Jenkinsfile)
Jenkins 端创建流水线任务,关联远程 Git 仓库,拉取 Jenkinsfile 并执行,步骤与原有方案一致,无额外配置:
- 登录 Jenkins → 新建任务 → 输入任务名称(如conda-ts-playwright-pipeline)→ 选择「流水线」→ 确定;
- 配置任务核心参数: 通用:勾选「丢弃旧的构建」,设置最大保留数为 10(避免磁盘占用); 流水线: 定义:选择「从 SCM 获取」; SCM:选择 Git; 仓库 URL:填写你的远程 Git 仓库地址; 凭证:私有仓库添加「用户名 + 密码」凭证并选择; 分支指定:*/main(或你的开发分支); 脚本路径:Jenkinsfile(项目根目录);
- 点击「保存」,完成 Pipeline 任务配置。
四、流水线触发与验证(与原有方案一致)
方式 1:手动触发(测试阶段,首选)
- 进入创建的 Pipeline 任务页面 → 左侧「立即构建」;
- 点击构建编号(如 #1)→ 「控制台输出」,实时查看流水线执行日志;
- 执行完成后,通过 Jenkins 页面查看「Conda+TS Playwright 自动化测试报告」,验证所有用例通过。
方式 2:Git WebHook 自动触发(生产阶段,推荐)
配置 Git 仓库 WebHook 后,本地git push或合并分支到 main 时,Jenkins 自动触发流水线,实现「代码提交即构建测试部署」。
- GitHub:WebHook 地址为http://服务器IP:8080/github-webhook/(末尾斜杠必加),触发事件选择「Just the push event」;
- GitLab:WebHook 地址为http://服务器IP:8080/project/任务名称,触发事件勾选「推送事件」,取消 SSL 验证(若无证书)。
流水线成功验证标准(新增 Python 服务验证)
- Jenkins 所有阶段显示蓝色对勾,控制台输出无报错,最后显示「Pipeline succeeded」;
- 访问 TS 服务:http://服务器IP:3000/ts/api,正常返回 TS 接口数据;
- 访问 Python 服务:http://服务器IP:5000/py/api,正常返回 Python 接口数据,且conda_env字段为ts-py-env(验证 Conda 环境激活成功);
- Jenkins 页面可查看 Playwright 测试报告,TS+Python 服务用例 100% 通过;
- 执行docker ps,生产容器正常运行,无退出;
- 执行docker exec 容器名称 conda info --envs,验证 Conda 环境正常存在且激活。
五、常见问题排查(新增 Conda 相关高频问题)
问题 1:Docker 构建时报错「conda: command not found」
原因:未使用 Miniconda3 官方镜像,或镜像中 conda 命令未加入环境变量;
解决方案:Dockerfile 基础镜像必须使用continuumio/miniconda3:latest,无需额外配置 conda 路径。
问题 2:容器内 Python 服务启动成功,但接口访问报「模块找不到」
原因:未激活 Conda 环境,Python 依赖未安装到指定环境;
解决方案:
- 检查 Dockerfile 中是否执行conda env create -f environment.yml;
- 启动脚本中添加source /opt/conda/bin/activate ts-py-env,确保激活 Conda 环境后再启动 Python 服务。
问题 3:Playwright 测试报错「Python 服务连接拒绝」
原因:Python 服务启动晚于 TS 服务,或服务未绑定到0.0.0.0;
解决方案:
- Python 服务代码中,Flask 启动需指定host='0.0.0.0'(允许容器外部访问);
- 启动脚本中,Python 服务后台运行后,添加sleep 3等待服务就绪,再启动 TS 服务。
问题 4:Jenkins 执行docker run时报错「权限不足」
原因:Jenkins 容器内用户无 Docker 操作权限;
解决方案:宿主机执行sudo chmod 666 /var/run/docker.sock,重启 Jenkins 容器。
问题 5:Conda 环境创建时报错「Solving environment: failed」
原因:environment.yml中依赖版本冲突,或 Conda 镜像源网络问题;
解决方案:
- 简化environment.yml,指定兼容的依赖版本;
- 在environment.yml中添加国内镜像源:
- yaml
- channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ - conda-forge
问题 6:容器启动后,TS 服务正常,Python 服务未运行
原因:启动脚本中 Python 服务未后台运行,或脚本无执行权限;
解决方案:
- 启动脚本中 Python 启动命令后加&(后台运行);
- Dockerfile 中添加RUN chmod +x start.sh,赋予脚本执行权限。
六、扩展优化(生产环境建议)
- Conda 环境缓存:Docker 构建时,将/opt/conda/pkgs目录挂载为卷,缓存 Conda 依赖包,提升后续构建速度;
- 多环境隔离部署:通过 Jenkins 参数化构建,配合不同的environment.yml和docker-compose.yml,实现 dev/test/prod 环境的 Conda/TS 依赖隔离;
- Python/TS 服务监控:在生产容器中集成supervisord,替代 Shell 启动脚本,实现服务监控和自动重启;
- 私有镜像仓库:搭建 Harbor,将生产镜像推送到私有仓库,避免镜像保存在单台服务器;
- 测试分层:将 Playwright 测试拆分为「冒烟测试」「回归测试」,流水线中可指定执行,提升测试效率;
- Conda 环境精简:生产阶段的 Conda 环境仅保留必要依赖,通过conda clean -a清理缓存,减小镜像体积。
总结
本次方案在原有 CI/CD 体系中无缝融入Conda,核心解决了「TS/Playwright 主工程中 Python 环境管理」的问题,实现了Conda+Node.js 双环境的容器化隔离与协同,关键亮点如下:
- 环境统一:所有环节(Conda/Node.js/ 测试 / 部署)均基于 Docker 运行,彻底消除环境不一致问题;
- 配置代码化:Conda 环境通过environment.yml管理,流水线通过Jenkinsfile管理,与项目代码一起托管到 Git,便于版本控制和团队协作;
- 轻量高效:Jenkins 无需内置任何业务环境,仅负责流水线编排,所有环境操作均在项目 Docker 镜像中完成,简化 Jenkins 配置;
- 全链路测试:Playwright 自动化测试覆盖 TS 主服务和 Conda 管理的 Python 辅助服务,测试作为强制卡点,保证交付质量;
- 可扩展性强:适配「TS 为主、Python 为辅」的各类项目,仅需调整environment.yml和 Dockerfile 中的依赖,即可快速迁移。
整套方案保持了原有 CI/CD 流程的简洁性和可落地性,同时弥补了 Python 环境管理的空白,适用于前端、后端、全栈(TS+Python)等各类项目的 CI/CD + 自动化测试需求。
