You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab Runner如何复用前序作业完整状态实现后续作业全量缓存

GitLab CI作业间环境复用解决方案

核心疑问说明

你无法通过artifacts或cache直接传递prepare-env作业的完整Docker容器状态。GitLab CI中每个作业都会基于指定镜像启动全新的独立容器,前序作业对容器系统层的修改(比如默认路径下的pip安装包)会随着作业容器销毁而消失,只有$CI_PROJECT_DIR工作目录下的文件可以通过artifacts或cache在作业间传递。

可行实现方案

方案1:将依赖安装到工作目录,通过artifacts传递(无需提前构建镜像,最贴合你的需求)

修改pip安装路径,将所有依赖安装到工作目录内,通过artifacts传递该目录,后续作业添加该路径到Python模块搜索路径即可直接使用已安装的依赖,配置示例如下:

stages:
  - prepare
  - stage1
  - stage2

# 统一所有作业的基础镜像,避免版本差异导致依赖不兼容
image: python:3.7

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  # 指定依赖安装目录
  DEP_DIR: "$CI_PROJECT_DIR/deps"

cache:
  paths:
    - .cache/pip

prepare-env:
  stage: prepare
  tags:
    - docker
  script:
    # 将依赖安装到指定的工作目录下
    - pip install --target=$DEP_DIR requests
    - pip list
  artifacts:
    # 传递依赖目录给后续所有作业
    paths:
      - $DEP_DIR
    # 可根据需求设置artifacts保留时间
    expire_in: 1 day

run-first-job:
  stage: stage1
  tags:
    - docker
  script:
    # 将依赖目录添加到Python模块搜索路径
    - export PYTHONPATH="$DEP_DIR:$PYTHONPATH"
    # 此时可直接导入requests使用
    - pip list
    - python -c "import requests; print(requests.__version__)"

run-second-job:
  stage: stage2
  tags:
    - docker
  script:
    - export PYTHONPATH="$DEP_DIR:$PYTHONPATH"
    - pip list
    - python -c "import requests; print(requests.__version__)"

方案2:流水线内构建临时Docker镜像(适合有系统级依赖的场景)

如果需要传递的不仅仅是Python依赖,还有apt安装包、系统配置等内容,可在prepare阶段通过Docker-in-Docker构建临时镜像,后续作业直接使用该镜像:

stages:
  - prepare
  - stage1
  - stage2

variables:
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"
  # 临时镜像名称
  TEMP_IMAGE: "ci-temp-python:latest"

prepare-env:
  stage: prepare
  tags:
    - docker
  image: docker:latest
  services:
    - docker:dind
  script:
    # 编写Dockerfile构建包含依赖的临时镜像
    - |
      cat > Dockerfile << EOF
      FROM python:3.7
      RUN pip install requests
      EOF
    - docker build -t $TEMP_IMAGE .
    # 推送到项目自带的容器镜像仓库,或者本地镜像缓存
    - docker push $TEMP_IMAGE

run-first-job:
  stage: stage1
  tags:
    - docker
  image: $TEMP_IMAGE
  script:
    - pip list
    - python -c "import requests; print(requests.__version__)"

run-second-job:
  stage: stage2
  tags:
    - docker
  image: $TEMP_IMAGE
  script:
    - pip list
    - python -c "import requests; print(requests.__version__)"

方案3:优化cache配置(适合跨流水线复用依赖)

如果你的依赖不会频繁变更,可以结合cache功能,跨流水线复用依赖包,避免每次运行都重新下载依赖:

  • 将pip缓存目录加入cache,就算是新的流水线也可以直接用本地缓存的安装包,无需从PyPI重新下载
  • 配合方案1使用可以进一步缩短作业运行时间

内容的提问来源于stack exchange,提问作者Cord Kaldemeyer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 14:45:00