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

Jenkins启动Docker容器时用户HOME目录缺失的解决方案咨询

问题描述

在主机部署Jenkins作为CI构建系统,部分流水线使用Docker容器执行构建(无Docker-in-Docker场景)。Jenkins会将自身OS用户(UID为114)注入Docker构建容器,但该用户在容器内不存在,导致无HOME目录,引发以下问题:

  • 构建过程中手动执行git clone命令失败;
  • npm install无法正常运行;
  • pip install无法正常运行。

详细场景

Jenkinsfile示例:

node {
    docker.image("bitnami/minideb:latest").inside() {
        echo "I am ..."
        sh "id"
    }
}

Jenkins Docker插件启动容器的命令:

docker run -t -d -u 114:121 -w ...... bitnami/minideb:latest

由于容器内无UID 114对应的用户,无HOME目录,后续执行conan config install git@code.repo.server.com:group/tools/conan.git时,因conan需将配置存储到~/.conan并执行git clone操作失败。

简化测试的Jenkinsfile及错误输出:

#!groovy

def docker_image = "cr.myownrepos.com/group/proj1/prj/algotest-launcher:1.6"

node {
    docker.withRegistry('https://cr.myownrepo.com/', '78e560d3-73d7-4f36-a884-3001a913b202'){
        docker.image(docker_image).inside() {

            stage('Build') {
                sshagent(['my_sshKey']) {
                    sh "export HOME=/tmp"
                    sh "git clone git@cr.myownrepo.com:bmd-se/group/conan.git"
                }
            }
        }
    }
}

错误输出:

+ git clone git@code.siemens.com:bmd-se/tools/conan.git
Cloning into 'conan'...
No user exists for uid 114
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

pip install的权限错误:

+ pip install tomli
WARNING: The directory '/.cache/pip' or its parent directory is not owned or is not writable by the current user. The cache has been disabled. Check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting tomli
  Downloading tomli-2.0.1-py3-none-any.whl (12 kB)
Installing collected packages: tomli
ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: '/.local'
Check the permissions.

核心问题

  • Jenkins始终以自身OS用户启动容器,该用户在容器内不存在;
  • 非root用户无法在容器内执行全局变更(如pip install);
  • 无HOME目录导致无法执行本地安装操作。

尝试过用docker.image(docker_image).inside("-u root")规避,但存在弊端:

  • 不再是非root容器;
  • git会因Jenkins注入的源码不属于root而报“dubious ownership”错误。

需求:如何在非root容器中为Jenkins注入的用户提供正常HOME目录及操作权限,解决上述问题?


解决方案

方法1:容器启动时动态创建匹配UID的用户

在流水线进入容器后,先通过当前UID/GID动态创建用户并配置HOME目录,确保后续操作有合法用户环境:

#!groovy

def docker_image = "cr.myownrepos.com/group/proj1/prj/algotest-launcher:1.6"

node {
    docker.withRegistry('https://cr.myownrepo.com/', '78e560d3-73d7-4f36-a884-3001a913b202'){
        docker.image(docker_image).inside() {

            stage('Prepare User') {
                sh '''
                    CURRENT_UID=$(id -u)
                    CURRENT_GID=$(id -g)
                    // 创建用户组(不存在则创建)
                    if ! getent group $CURRENT_GID > /dev/null; then
                        groupadd -g $CURRENT_GID jenkins-build
                    fi
                    // 创建用户(不存在则创建)并生成HOME目录
                    if ! getent passwd $CURRENT_UID > /dev/null; then
                        useradd -u $CURRENT_UID -g $CURRENT_GID -m -d /home/jenkins-build jenkins-build
                    fi
                    // 导出HOME环境变量
                    export HOME=/home/jenkins-build
                '''
            }

            stage('Build') {
                sshagent(['my_sshKey']) {
                    sh '''
                        git clone git@cr.myownrepo.com:bmd-se/group/conan.git
                        // 依赖安装指定到用户HOME目录,避免全局权限问题
                        pip install tomli --user
                        npm install --prefix $HOME/.local
                    '''
                }
            }
        }
    }
}

说明:

  • 通过id -u/id -g获取Jenkins注入的UID/GID,动态创建对应用户和组;
  • -m参数自动生成/home/jenkins-build作为HOME目录;
  • 依赖安装使用--user(pip)或--prefix(npm)指定到用户私有目录,无需全局权限。

方法2:定制镜像预先创建匹配UID的用户

如果流水线频繁使用同一镜像,可直接在Dockerfile中预先创建匹配Jenkins UID的用户,省去每次容器启动的动态创建步骤:

固定UID版本Dockerfile

FROM cr.myownrepos.com/group/proj1/prj/algotest-launcher:1.6

# 创建匹配Jenkins UID/GID的用户
RUN groupadd -g 121 jenkins-build && \
    useradd -u 114 -g jenkins-build -m -d /home/jenkins-build jenkins-build

# 配置HOME环境变量
ENV HOME=/home/jenkins-build

可变UID版本Dockerfile(适配不同Jenkins环境)

FROM cr.myownrepos.com/group/proj1/prj/algotest-launcher:1.6

ARG JENKINS_UID=114
ARG JENKINS_GID=121

RUN groupadd -g $JENKINS_GID jenkins-build && \
    useradd -u $JENKINS_UID -g jenkins-build -m -d /home/jenkins-build jenkins-build

ENV HOME=/home/jenkins-build

构建命令:

docker build --build-arg JENKINS_UID=114 --build-arg JENKINS_GID=121 -t custom-build-image .

方法3:调整git配置规避所有权检查(仅临时应急)

若不得不使用root用户启动容器,可临时关闭git的所有权检查解决“dubious ownership”错误:

docker.image(docker_image).inside("-u root") {
    stage('Fix Git Ownership') {
        sh "git config --global --add safe.directory '*'"
    }
    // 后续构建步骤
}

说明:此方法仍存在root用户的安全风险,仅在无法使用其他方案时临时使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:42:12