Jenkins在Docker中运行中的坑

jenkins是什么?

  Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具,起源于Hudson(Hudson是商用的),主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写,可在Tomcat等流行的servlet容器中运行,也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。常用的版本控制工具有SVN、GIT,构建工具有Maven、Ant、Gradle。
上面的介绍是抄的(逃,简单讲,就是Jenkins能帮我们自动编译,测试,发布软件

安装运行

Jenkins有单独的war包,通过java -jar jenkins.war直接就可以运行(官网下载,选择Generic Java package (.war),或者官方镜像),选择LTS Releases 中的war-stable),但是jre环境,当然对于熟悉Java的人来说,这个是配置一下即可。本文介绍在Docker中运行Jenkins以及会遇到的一些问题。
* 操作系统:Ubuntu 18.04.3 LTS * docker版本:19.03.4 * jdk版本:java version "1.8.0_221"

vim中打开中文有时候会乱码,可以通过下面命令解决:

1
sudo locale-gen zh_CN.UTF-8
好了,让我们开始安装Jenkins
首先,编写一份自定义的Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM jenkins/jenkins:lts

USER root

RUN echo ' \n\
deb http://mirrors.aliyun.com/debian stretch main contrib non-free \n\
deb-src http://mirrors.aliyun.com/debian stretch main contrib non-free \n\
deb http://mirrors.aliyun.com/debian stretch-updates main contrib non-free \n\
deb-src http://mirrors.aliyun.com/debian stretch-updates main contrib non-free \n\
deb http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-free \n\
deb-src http://mirrors.aliyun.com/debian-security stretch/updates main contrib non-free ' > /etc/apt/sources.list

RUN cat /etc/apt/sources.list

#更新源并安装缺少的包
RUN apt-get update && apt-get install -y gcc g++ make openssl pkg-config


USER jenkins
基础镜像是jenkins/jenkins:lts,观察一下这个镜像
发现它是基于FROM openjdk:8-jdk-stretch,这是带有jdk的debian 9镜像。所以我在Dockerfile中修改了apt源,这里使用了阿里云的apt源(\n\是换行加上续行符)。

再配合docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
version: '3'
services:
jenkins:
build: .
volumes:
- ./data:/var/jenkins_home
environment:
- "JAVA_OPTS=-Duser.timezone=Asia/Shanghai -Xms1g -Xmx1g"
ports:
- 127.0.0.1:8080:8080
- 50000:50000
现在我们就可以启动Jenkins了,打开终端,键入命令:
1
docker-compose up
这时候,我们会遇到错误:
1
2
jenkins_1  | touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied
jenkins_1 | Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?
看描述是权限问题,观察一下目录下的data文件夹:
1
drwxr-xr-x  2 root       root       4096 11月 17 20:47 data
发现目录的属主是root用户,这是什么原因呢?

原因探究

查看Jenkins容器的当前用户和目录/var/jenkins_home属主,我们发现当前用户是Jenkins/var/jenkins_home属主用户是jenkins

1
2
3
4
5
6
7
8
docker run -ti --rm --entrypoint="/bin/bash"  jenkins/jenkins:lts  -c "whoami && id"
jenkins
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)

docker run -ti --rm --entrypoint="/bin/bash" jenkins/jenkins:lts -c "ls -la /var"
drwxr-xr-x 1 root root 4096 Oct 17 08:29 cache
drwxr-xr-x 2 jenkins jenkins 4096 Nov 17 14:05 jenkins_home

上述命令中,--rm选项是让容器退出时自动清除,--entrypoint是覆盖镜像中的ENTRYPOINT
现在我们知道了,因为/var/jenkins_home映射到本地数据卷时,目录的拥有者变成了root用户,所以出现了Permission denied的问题。
发现问题之后,相应的解决方法也很简单:把当前目录的拥有者赋值给uid 1000,再启动"jenkins"容器就一切正常了。
1
sudo chown -R 1000:1000 data
这时利用浏览器访问 "http://localhost:8080/" 就可以看到Jenkins的经典Web界面了。

参考: * 谈谈 Docker Volume 之权限管理(一)