3、环境搭建:Python虚拟环境配置、Docker容器化环境、持续集成(CI)环境准备

好,咱们直接进入正题。环境搭建这事儿,说简单也简单,说复杂能折腾你一整天。我见过太多人,代码写得挺溜,结果一换机器就跑不起来,为啥?环境没管好。这一章,我就把我在驱动集成验证项目中,反复踩坑又填坑的经验,一次性给你讲透。

3.1 Python虚拟环境:隔离是美德

你想想看,一个项目依赖Python 3.8,另一个项目非要3.10,要是全装系统里,迟早乱套。虚拟环境就是干这个的——给每个项目一个独立的Python解释器和包空间。

3.1.1 创建与激活

我个人习惯用 venv,Python 3.3+ 自带,不用额外装。命令很简单:

# 创建虚拟环境,名字叫 venv_driver
python3 -m venv venv_driver

# 激活(Linux/Mac)
source venv_driver/bin/activate

# 激活(Windows)
venv_driver\Scripts\activate

# 退出
deactivate

激活后,终端前面会出现 (venv_driver) 的提示符。这时候你装任何包,都只在这个环境里生效。

我的小习惯: 我一般把虚拟环境建在项目根目录下,名字就叫 .venv 或 venv,然后加到 .gitignore 里。这样团队其他人拉下来代码,自己重建一个就行。

3.1.2 依赖管理:requirements.txt

环境搭好了,怎么让别人复现?用 requirements.txt。把当前环境的所有包导出来:

pip freeze > requirements.txt

别人拿到项目后,一条命令就能装好:

pip install -r requirements.txt

我曾经在一个项目里,因为忘了导出这个文件,导致同事折腾了两天才跑起来。嗯,从那以后,我每次提交代码前都会检查一下 requirements.txt 是不是最新的。

3.1.3 避坑指南:Python版本不一致

我曾经踩过的坑: 本地用 Python 3.10 开发,CI 环境用的是 3.8。结果有个语法在 3.8 上不支持,CI 直接挂了。后来我学乖了,在项目根目录放一个 .python-version 文件,里面写上 3.8.10,再用 pyenv 来管理。

3.2 Docker容器化环境:一次构建,到处跑

虚拟环境解决了Python包的问题,但驱动验证往往还依赖系统库、内核模块、甚至特定版本的gcc。这时候Docker就派上用场了。

3.2.1 为什么用Docker?

说白了,Docker把整个运行环境打包成一个镜像。你本地测好了,推到仓库,CI拉下来直接用,结果完全一致。我参与过一个项目,测试环境是Ubuntu 20.04,生产环境是CentOS 7,依赖的库路径都不一样。用Docker后,这些问题全消失了。

3.2.2 编写Dockerfile

一个典型的驱动验证环境Dockerfile长这样:

# 基于Ubuntu 20.04
FROM ubuntu:20.04

# 设置非交互模式,避免安装时卡住
ENV DEBIAN_FRONTEND=noninteractive

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    build-essential \
    linux-headers-$(uname -r) \
    python3.8 \
    python3-pip \
    git \
    vim \
    && rm -rf /var/lib/apt/lists/*

# 设置工作目录
WORKDIR /workspace

# 复制项目文件
COPY . .

# 安装Python依赖
RUN pip3 install -r requirements.txt

# 默认命令
CMD ["/bin/bash"]
注意: 驱动验证经常需要访问宿主机的内核头文件。如果Docker容器里 uname -r 和宿主机不一致,编译驱动时会报错。我建议在运行容器时,把宿主机的 /lib/modules 挂载进去。

3.2.3 构建与运行

# 构建镜像,标签为 driver-verify:latest
docker build -t driver-verify:latest .

# 运行容器,挂载内核模块目录
docker run -it --rm \
    -v /lib/modules:/lib/modules:ro \
    -v $(pwd):/workspace \
    driver-verify:latest

你想想看,有了这个容器,不管是在你笔记本上,还是在服务器上,甚至是在同事的Mac上,都能跑出一样的结果。这就是容器化的魅力。

3.3 持续集成(CI)环境准备:自动化验证的基石

环境搭好了,代码写完了,总不能每次都手动跑测试吧?CI就是帮你自动干这活的。我常用的CI平台有GitHub Actions、GitLab CI、Jenkins。这里以GitHub Actions为例,因为它和GitHub仓库集成得最好。

3.3.1 工作流文件结构

在项目根目录创建 .github/workflows/verify.yml:

name: Driver Verification

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  verify:
    runs-on: ubuntu-20.04

    steps:
    - name: 检出代码
      uses: actions/checkout@v3

    - name: 设置Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.8'

    - name: 安装依赖
      run: |
        python -m venv venv
        source venv/bin/activate
        pip install -r requirements.txt

    - name: 运行驱动验证
      run: |
        source venv/bin/activate
        python verify_driver.py

3.3.2 缓存依赖,加速构建

每次CI都重新装一遍依赖,太慢了。我建议加上缓存:

    - name: 缓存pip
      uses: actions/cache@v3
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
        restore-keys: |
          ${{ runner.os }}-pip-

这样只要 requirements.txt 没变,就直接用缓存,构建时间能缩短一半以上。

3.3.3 矩阵测试:多版本验证

驱动要支持多个内核版本?没问题,用矩阵策略:

    strategy:
      matrix:
        python-version: ['3.8', '3.9', '3.10']
        kernel-version: ['5.4', '5.10', '5.15']

    steps:
    - name: 设置Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}

这个矩阵会生成 3×3=9 个任务,并行跑。哪个版本有问题,一目了然。

注意: 矩阵任务多了,CI并发数可能不够。GitHub Actions免费版只有20个并发。我建议在 requirements.txt 里只放核心依赖,别把测试工具也塞进去,减少构建时间。

3.4 本章知识体系总览

下面这张图,把本章的核心逻辑串起来了。你可以看到,从本地开发到CI验证,每一层都在解决不同的问题。

环境搭建知识体系 本地开发环境 Python虚拟环境 (venv) 依赖管理 (requirements.txt) 系统库与内核头文件 容器化环境 Dockerfile 定义环境 挂载宿主机内核模块 一次构建,到处运行 持续集成环境 GitHub Actions 工作流 缓存加速 + 矩阵测试 自动触发,并行验证 三层环境层层递进,确保驱动验证的可复现性与自动化

这三层环境,说白了就是一套组合拳。虚拟环境管Python包,Docker管系统依赖,CI管自动化流程。少了哪一层,都可能出幺蛾子。我建议你从第一层开始,一步步搭建,别想一口吃成胖子。

最后说一句: 环境搭建这事儿,别怕麻烦。前期花一小时配好,后期能省你十小时。我在项目里吃过太多亏了,现在每接手一个新项目,第一件事就是搭环境、写Dockerfile、配CI。习惯成自然。

可可精品资料库