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

如何配置Docker始终重新安装Python依赖?解决Git依赖更新失效问题

跨仓库Python项目部署问题:更新依赖后Docker/K8s未拉取最新代码

背景

正在开发一个跨多代码仓库的大型Python项目,采用Github Actions、Docker和Kubernetes部署,对这些技术及Python均较为陌生。项目的Python仓库依赖其他仓库,在requirements.txt中通过-e git+https://${GH_PAT}@github.com/xyz/foo@main#egg=foo&subdirectory=src这类方式安装依赖,Dockerfile中包含RUN步骤执行pip install -r requirements.txt。

问题

更新某个依赖后,Docker/Kubernetes常常不会重新拉取并安装该仓库。例如:bar依赖foo,在foo的main分支添加新功能并推送后,bar中使用这些新功能,构建Docker镜像并部署到K8s,但K8s持续出现ModuleNotFoundError,尽管该模块已存在于foo的main分支。

排查发现

查阅资料后推测问题源于Docker缓存,当前Docker配置了cache-from: type=gha和cache-to: type=gha,mode=max。

请问是否有办法让Docker始终执行pip install -r requirements.txt?或是流程中其他环节需要优化?


Dockerfile

FROM python:3.10.9

# copy the requirements file into the image
COPY ./requirements.txt /app/requirements.txt

# switch working directory
WORKDIR /app

# install the dependencies and packages in the requirements file
RUN --mount=type=secret,id=gh_pat \
  GH_PAT=$(cat /run/secrets/gh_pat) \
  pip install -r requirements.txt

RUN --mount=type=secret,id=aws_access_key_id \
    --mount=type=secret,id=aws_secret_access_key \
    mkdir /root/.aws && \
    echo "[default]" > /root/.aws/credentials && \
    echo "aws_access_key_id=$(cat /run/secrets/aws_access_key_id)" >> /root/.aws/credentials && \
    echo "aws_secret_access_key=$(cat /run/secrets/aws_secret_access_key)" >> /root/.aws/credentials

# copy every content from the local file to the image
COPY . /app

# configure the container to run in an executed manner
CMD [ "python", "./foo.py" ]

Deployment YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo-deployment
  namespace: foo
  labels:
    app: foo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foo
  template:
    metadata:
      labels:
        app: foo
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/arch
                operator: In
                values:
                - amd64
                - arm64
              - key: eks.amazonaws.com/nodegroup
                operator: In
                values: [foo]
      containers:
      - name: matcher-container
        image: ***.***.ecr.us-east-*.amazonaws.com/foo:latest
        imagePullPolicy: Always
        ports:
        - name: http
          containerPort: 80
      nodeSelector:
        kubernetes.io/os: linux

解决方案

1. 强制Docker跳过缓存执行pip install

Docker缓存逻辑是:若requirements.txt内容未变化,则复用之前的缓存层。但你的依赖指向Git分支,文件本身无修改,因此Docker会跳过重新安装。可通过以下方式强制跳过缓存:

  • 在pip install命令中添加--no-cache-dir参数,同时增加一个动态标识让Docker认为指令变更,比如:
    RUN --mount=type=secret,id=gh_pat \
      GH_PAT=$(cat /run/secrets/gh_pat) \
      pip install --no-cache-dir -r requirements.txt && \
      echo "Install completed at $(date)" > /tmp/install_timestamp
    
  • 构建镜像时直接添加--no-cache参数完全禁用缓存,适合需要强制更新的场景:
    docker build --no-cache -t your-image:tag .
    

2. 优化依赖引用方式

依赖指向Git分支(如main)的问题在于,即使分支更新,pip默认不会重新拉取最新代码(因为版本标识未变)。可改为以下方式:

  • 使用Git commit哈希代替分支名:将requirements.txt中的@main替换为具体的commit哈希(如@a1b2c3d),每次依赖仓库更新时手动修改该哈希,Docker会因requirements.txt内容变化重新执行pip install。
  • 给依赖仓库打语义化版本标签,用标签代替分支名(如@v1.0.1),更新版本时修改标签即可触发Docker重新安装。

3. 调整Github Actions缓存策略

若使用Github Actions的Docker缓存,cache-from: type=gha会复用历史构建缓存。可针对pip install层设置不缓存,或在需要更新依赖时手动触发构建并禁用缓存,比如在Github Actions构建命令中添加--no-cache参数,或让缓存键包含依赖仓库的最新commit哈希。

4. 优化Kubernetes镜像标签策略

你的Deployment已设置imagePullPolicy: Always,但需注意:

  • 避免使用latest标签,即使镜像更新,Kubernetes可能因标签未变而不重新部署。建议使用唯一标签,如Git commit哈希、时间戳或版本号,每次构建生成新标签后,同步更新Deployment中的镜像标签。

5. 添加依赖安装验证步骤

在Dockerfile中加入验证步骤,确保依赖安装正确,避免部署后才发现问题:

RUN pip show foo | grep -q "Version:" || (echo "foo not installed correctly" && exit 1)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:24:52