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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 00:30:09