如何在TeamCity Azure构建代理上持久化安装Mono?
哎,这个坑我之前踩过!你在容器里装完Mono重启代理就丢,本质是因为TeamCity代理跑在Docker容器里——容器默认的文件系统是临时层,重启后所有容器内的修改都会被重置回镜像初始状态。要搞定持久化,有两种靠谱的方法,我给你详细拆解:
方法一:自定义TeamCity代理镜像(推荐,最稳定)
这个思路是把Mono直接预装到代理镜像里,这样每次启动容器,Mono都是现成的,完全不用担心丢失。
编写Dockerfile
在你的CoreOS虚拟机上创建一个Dockerfile,内容如下:# 基于官方TeamCity代理镜像 FROM jetbrains/teamcity-agent:latest # 切换到root用户执行安装操作(官方镜像默认用buildagent用户,没权限装软件) USER root # 按照Mono官方步骤添加源并安装完整包,适配Ubuntu基础镜像(官方代理镜像是Ubuntu内核) RUN apt-get update && \ apt-get install -y gnupg ca-certificates && \ apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF && \ echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | tee /etc/apt/sources.list.d/mono-official-stable.list && \ apt-get update && \ # 指定TeamCity要求的Mono兼容版本(这里适配Mono4.5需求) apt-get install -y mono-complete=6.8.0.105-0xamarin1+ubuntu2004b1 && \ # 清理缓存减小镜像体积 apt-get clean && rm -rf /var/lib/apt/lists/* # 切回buildagent用户,保持和官方镜像一致的运行权限 USER buildagent构建自定义镜像
在Dockerfile所在目录执行命令:docker build -t my-teamcity-agent-with-mono .如果你的虚拟机在Azure上,也可以把镜像推送到Azure Container Registry(ACR),方便后续ARM模板直接调用。
修改ARM模板使用自定义镜像
找到你ARM模板中TeamCity代理容器的配置部分,把原来的image值从jetbrains/teamcity-agent:latest改成你刚构建的镜像名my-teamcity-agent-with-mono(如果推到ACR了,就用你的ACR名称.azurecr.io/my-teamcity-agent-with-mono)。重新部署模板后,新的代理容器自带Mono,重启也不会丢。
方法二:挂载宿主机持久化目录到容器
如果不想自定义镜像,也可以把Mono的安装目录挂载到CoreOS宿主机的本地目录,这样容器重启后,Mono的文件还在宿主机上。
在CoreOS宿主机创建持久化目录
执行命令创建目录并设置正确权限(TeamCity代理容器用的是uid=1000的buildagent用户,要确保它能读写这个目录):sudo mkdir -p /opt/mono-persist sudo chown 1000:1000 /opt/mono-persist修改ARM模板的容器挂载配置
在模板的代理容器配置里,添加volume挂载规则:"containers": [ { "name": "teamcity-agent", "image": "jetbrains/teamcity-agent:latest", "volumeMounts": [ { "name": "mono-storage", "mountPath": "/usr/lib/mono" # 这个是Mono默认安装目录,可先在容器里用`find / -name mono`确认 } ], // 其他容器配置... } ], "volumes": [ { "name": "mono-storage", "hostPath": { "path": "/opt/mono-persist", "type": "DirectoryOrCreate" } } ]重新部署并安装Mono
部署更新后的模板,进入代理容器安装Mono,这次安装的文件会直接写到宿主机的/opt/mono-persist目录,重启容器后不会丢失。
额外注意:让TeamCity识别Mono
安装完Mono后,TeamCity可能还是提示找不到Mono4.5_x86,这时候需要手动指定路径:
- 进入代理容器的配置目录(默认是
/data/teamcity_agent/conf),编辑buildAgent.properties,添加一行:system.Mono4.5_x86=/usr/bin/mono - 重启代理服务,TeamCity就能检测到Mono了。
内容的提问来源于stack exchange,提问作者Rob Lyndon

