下载镜像
使用 docker search
命令搜索 jenkins 镜像,结果如下:
此处选用 jenkinsci/blueocean
版本,这次是 Jenkins 官方推荐的镜像版本。因为在实践中发现官方镜像使用中会出现大量插件安装失败的问题,针对此问题,可以选择手动上传插件安装。这里就不再详细讨论此问题。
使用 docker pull
命令拉取镜像
docker pull jenkinsci/blueocean
运行容器
docker run \
--name jenkins-blueocean \
-d \
-p 9000:8080 \
-p 50000:50000 \
-v /mnt/jenkins-data:/var/jenkins_home \
-v /usr/lib/jvm/java-1.8.0:/usr/lib/jvm/java-1.8.0 \
-v /usr/local/maven3/maven3:/usr/local/maven3/maven3 \
jenkinsci/blueocean
参数说明
--name
定义一个容器的名字,如果没有指定,那么会自动生成一个随机数字符串当做UUID
-d
标识是让 docker 容器在后台运行
-p 9000:8080
端口映射,将宿主机9000端口映射到容器8080端口
-p 50000:50000
50000端口是基于JNLP的Jenkins代理(slave)通过TCP与 Jenkins master
进行通信的端口。
-v /mnt/jenkins-data:/var/jenkins_home
绑定一个数据卷,/mnt/jenkins-data
是宿主机数据卷
-v /usr/lib/jvm/java-1.8.0:/usr/lib/jvm/java-1.8.0
映射 JDK 目录
-v /usr/local/maven3/maven3:/usr/local/maven3/maven3
映射 Maven 目录
补充说明,这里映射 JDK 和 Maven 目录是因为Jenkins 运行在容器内,通过 ssh 交互式的访问的时候是无法访问宿主机的环境变量的,在折腾了半天后我通过修改容器内的 /etc/profile 让 maven 正常运行起来,否则在后续构建项目的时候会收到找不到 mvn 的错误。这里这种操作方式显示是不好的实践,理论可以通过构建 dockerFile 在编织镜像时传入环境变量,后续有机会进一步研究。
配置Jenkins
容器启动后,通过http://<ipaddress>:9000
就可以访问 Jenkins 界面了
管理员初始密码被放到了/var/jenkins_home/secrets/initialAdminPassword
文件中。
docker exec jenkins-blueocean cat /var/jenkins_home/secrets/initialAdminPassword
Jenkins 解锁成功后,安装插件,此处选择安装推荐的插件,等待安装完成即可
插件安装完成,创建一个管理员用户,配置 Jenkins 实例地址,Jenkins 就安装完成了。
创建项目
此处以构建一个 Spring Boot 项目举例
准备工作
-
安装 Publish over SSH 插件
1.在系统管理,插件管理中安装 Publish Over SSH
2.在系统管理,配置一节找到 Publish over SSH 并配置你的部署项目机器
-
准备一个 git 仓库
用户拉取需要构建的代码
-
准备运行项目的目标机器
项目构建完成将传输到目标机器并启动
新建项目
-
选择构建一个自由风格的软件项目
-
源码管理一栏指定代码仓库地址,代码分支,并添加用于身份验证的凭据
-
构建一栏选择执行 shell 并输入打包命令
-
构建后操作选择
Send build artifacts over SSH
,并指定目标机器,选择文件传输目录,并指定需要执行的命令
常见问题
-
构建提示 mvn: command not found
Jenkins 所在容器未配置环境变量,可以通过在容器内配置环境变量或尝试读取宿主机的环境变量
-
构建提示 ERROR: Exception when publishing, exception message [Exec exit status not zero. Status [126]]
目标机器上的启动脚本无执行权限,需要添加权限
-
构建提示 ERROR: Exception when publishing, exception message [Exec exit status not zero. Status [-1]]
目标机器上的执行脚本查询当前项目进程并 kill 时将 Jenkins 进程一并杀掉了,需要排除查找进程自身
pid=`ps -ef|grep $APP_NAME|grep java |grep -v grep|awk '{print $2}' `