如何在Bitbucket流水线中访问自定义镜像内的~/.m2目录?
问题
刚接触DevOps,正在为Bitbucket创建自定义镜像,镜像中已安装Maven并配置了~/.m2/settings.xml,希望能在流水线步骤中全局使用。
Docker镜像配置
FROM maven:3.9-eclipse-temurin-19-alpine RUN apk add --no-cache wget net-tools RUN mkdir -p /root/.m2 && chmod -R 777 /root/.m2 && touch /root/.m2/settings.xml ENV MAVEN_CONFIG="/root/.m2" WORKDIR /opt/atlassian/bitbucketci/agent/build RUN ls -lah /root/.m2 && (cat /root/.m2/settings.xml || echo "none") CMD ["tail", "-f", "/dev/null"]
特意添加了net-tools测试可用性,也创建了测试用的.m2目录及settings.xml并调试确认创建成功。
测试流水线配置
image: name: <docker username>/<custom image>:1 username: $DOCKER_USERNAME password: $DOCKER_PASSWORD pipelines: default: - step: name: "Pull bash script" script: - ls . && echo "This is cwd" - echo $MAVEN_HOME - telnet - ls ~/.m2 | echo "no m2" - ls /usr/share/maven | echo "nothing in usr"
遇到的问题:无法在流水线中访问镜像里创建的~/.m2目录,镜像中安装的内容好像没和流水线步骤共享。
解决方案
1. 核心问题:Bitbucket流水线的运行用户
Bitbucket Pipelines默认不会以root用户运行流水线,而是使用非root用户(通常是atlassian)。你在镜像里创建的.m2目录在/root/.m2,属于root用户的家目录,而流水线运行时~指向的是当前运行用户的家目录(比如/home/atlassian),所以自然访问不到。
有两种解决思路:
思路一:在镜像中为流水线默认用户配置.m2
修改Dockerfile,切换到流水线默认用户(如果镜像中没有该用户,先创建),然后在其家目录下创建.m2目录和配置文件:
FROM maven:3.9-eclipse-temurin-19-alpine RUN apk add --no-cache wget net-tools # 创建并切换到atlassian用户(Bitbucket流水线默认运行用户) RUN adduser -D atlassian USER atlassian # 在当前用户家目录创建.m2及配置文件 RUN mkdir -p ~/.m2 && chmod -R 777 ~/.m2 && touch ~/.m2/settings.xml ENV MAVEN_CONFIG="/home/atlassian/.m2" WORKDIR /opt/atlassian/bitbucketci/agent/build # 验证配置是否生效 RUN ls -lah ~/.m2 && (cat ~/.m2/settings.xml || echo "none") CMD ["tail", "-f", "/dev/null"]
思路二:让流水线以root用户运行
如果不想修改镜像,可以直接在流水线的step中指定使用root用户,这样~就指向/root,就能访问到你之前创建的.m2目录:
image: name: <docker username>/<custom image>:1 username: $DOCKER_USERNAME password: $DOCKER_PASSWORD pipelines: default: - step: name: "Pull bash script" user: root # 添加这一行,指定用root运行 script: - ls . && echo "This is cwd" - echo $MAVEN_HOME - telnet - ls ~/.m2 || echo "no m2" # 这里把|改成||,只有ls失败时才输出提示 - ls /usr/share/maven || echo "nothing in usr"
2. 调试命令的坑
你原来的调试命令ls ~/.m2 | echo "no m2"有问题,管道符|会把ls的输出传给echo,但不管ls是否成功,echo都会执行,导致你误以为目录不存在。应该改成ls ~/.m2 || echo "no m2",这样只有当ls命令执行失败(目录不存在)时,才会输出"no m2",避免误导调试。
内容的提问来源于stack exchange,提问作者rabih
相关产品推荐
相关产品推荐

