在现代软件开发流程中,持续集成与持续部署(CI/CD)已成为提升交付效率与质量的核心引擎。Jenkins作为业界领先的开源自动化服务器,结合Docker容器化技术,能够构建出稳定、可移植且易于管理的CI/CD环境。本文将手把手带你完成从环境准备到Jenkins上线的全过程,涵盖Java 21升级、Docker环境搭建、容器化部署及安全配置等关键步骤,助你快速搭建一套现代化的自动化构建平台。
一、 基础环境准备:拥抱Java 21与Docker
一个稳固的地基是成功的一半。部署Jenkins前,我们需要确保运行环境是最新且稳定的。首先,我们将系统Java版本升级至Java 21,以获得更好的性能与新特性支持。同时,安装并配置Docker,为后续的容器化部署铺平道路。容器化部署的优势在于环境隔离、依赖统一和快速部署,这也是迈向更高级的容器编排技术(如Kubernetes (K8s))的第一步。
升级Java至21版本是首要任务。Jenkins本身基于Java运行,新版本Java能带来更优的垃圾回收机制和运行时性能。操作前,请先检查当前Java版本:
# 查看当前Java版本
java -version
# 查看所有已安装的Java版本
update-alternatives --display java
确认后,开始安装Java 21。我们推荐使用OpenJDK发行版,它开源且兼容性好。执行以下安装命令:
# 更新软件包列表
sudo apt update
# 安装OpenJDK 21
sudo apt install -y openjdk-21-jdk openjdk-21-jre
# 验证安装
java -version
安装完成后,预期会看到类似输出:
openjdk version "21.0.x" 2024-xx-xx
OpenJDK Runtime Environment (build 21.0.x+xx-Ubuntu-...)
OpenJDK 64-Bit Server VM (build 21.0.x+xx-Ubuntu-..., mixed mode, sharing)
接下来需要配置系统默认的Java版本,特别是当系统中存在多个Java版本时。使用update-alternatives命令进行管理:
# 配置默认Java版本
sudo update-alternatives --config java
# 会显示类似以下内容:
# Selection Path Priority Status
# ------------------------------------------------------------
# 0 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2111 auto mode
# 1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
# * 2 /usr/lib/jvm/java-21-openjdk-amd64/bin/java 2111 manual mode
# 输入序号选择Java 21(通常是最新版本的序号)
# 例如输入:0 或 2
# 同样配置javac
sudo update-alternatives --config javac
为了让系统应用和Jenkins能正确识别Java环境,必须设置JAVA_HOME环境变量。编辑profile文件:
# 查找Java 21安装路径
sudo update-alternatives --config java
# 记下Java 21的路径,例如:/usr/lib/jvm/java-21-openjdk-amd64
# 编辑环境配置文件
sudo nano /etc/environment
在文件末尾添加或修改环境变量定义,指向Java 21的安装路径。例如,添加如下行:
JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"
保存并退出编辑器(通常使用ESC键后输入:wq命令)。之后,使配置立即生效:
# 使配置生效
source /etc/environment
# 验证JAVA_HOME
echo $JAVA_HOME
java -version
⚠️ 重要提示:在确认新版本Java工作完全正常后,再考虑卸载旧版本,以避免不必要的兼容性问题。卸载命令如下:
# 列出所有Java相关包
dpkg -l | grep -i jdk
# 卸载JDK 11
sudo apt remove -y openjdk-11-jdk openjdk-11-jre
# 清理残留配置
sudo apt autoremove -y
sudo apt autoclean
最后,执行全面的验证,确保升级成功:
# 检查Java版本
java -version
# 检查javac版本
javac -version
# 检查JAVA_HOME
echo $JAVA_HOME
# 检查PATH
which java
当所有命令都显示Java 21相关信息时,恭喜你,基础环境升级成功!✅
二、 搭建容器化基石:安装与配置Docker
完成Java升级后,我们进入容器化部署的核心环节——安装Docker。Docker将应用程序及其所有依赖打包在一个轻量级、可移植的容器中,是实现环境一致性的利器。首先,清理可能存在的旧版本Docker,避免冲突:
sudo apt remove docker docker-engine docker.io containerd runc
接着,更新系统包索引并安装必要的依赖工具:
# 更新软件包索引
sudo apt update
# 安装必要的依赖包
sudo apt install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
software-properties-common
为了从官方源安全地安装Docker,需要添加Docker的GPG密钥和软件仓库:
# 创建密钥目录
sudo mkdir -p /etc/apt/keyrings
# 下载并添加Docker GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 设置密钥权限
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | sudo tee /etc/apt/sources.list.d/docker.list
现在,可以安装Docker Engine(社区版)及其命令行工具:
# 更新软件包索引
sudo apt update
# 安装Docker及相关组件
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后,启动Docker服务并设置为开机自启,确保服务持久运行:
# 启动Docker服务
sudo systemctl start docker
# 设置开机自启动
sudo systemctl enable docker
# 检查Docker状态
sudo systemctl status docker
关键步骤:为了避免每次使用docker命令都需要sudo权限,需要将当前用户加入docker用户组:
# 创建docker用户组(通常已存在)
sudo groupadd docker 2>/dev/null || true
# 将当前用户添加到docker组
sudo usermod -aG docker $USER
# 刷新用户组权限(二选一)
# exit 后重新连接服务器
执行此命令后,需要退出当前终端并重新登录,用户组变更才会生效。
最后,运行一个测试容器来验证Docker安装是否成功:
# 检查Docker版本
docker --version
# 运行测试容器
docker run hello-world
如果一切正常,你将看到来自Docker Hub的欢迎信息:
Hello from Docker!
This message shows that your installation appears to be working correctly.
如果遇到网络超时或连接Docker Hub失败的错误(这在某些地区很常见),通常是因为网络问题。一个高效的解决方案是配置国内镜像加速器,例如阿里云镜像加速服务,能极大提升镜像拉取速度[AFFILIATE_SLOT_1]。配置方法如下:
# 直接运行命令:
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://地址.mirror.aliyuncs.com",//替换成你的镜像加速的地址
"https://docker.1panel.live",
"https://docker.rainbond.cc"
]
}
EOF
# 重启Docker
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证
docker info | grep -A 10 "Registry Mirrors"
# 测试拉取镜像
docker run hello-world
# 如果成功,应该看到:
# Hello from Docker!
# This message shows that your installation appears to be working correctly.
此外,我们还需要Docker Compose工具,它用于定义和运行多容器Docker应用程序。新版本的Docker Desktop通常已包含Compose插件,可以通过以下命令验证:
# 检查Docker Compose版本
docker compose version
如果显示版本号(例如v2.24.5),则说明已安装。若未安装,可使用以下命令手动安装:
# 下载Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 创建软链接
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# 验证安装
docker-compose --version
三、 核心部署:使用Docker Compose运行Jenkins
环境就绪后,我们开始部署Jenkins。采用Docker Compose方式部署,能够通过一个YAML文件定义所有服务、网络和卷,实现一键式部署和配置即代码,管理起来非常清晰。
首先,为Jenkins创建一个专属的项目目录,并规划好用于持久化数据的子目录:
# 创建Jenkins项目目录(可以在你自己想放的目录下,我的在/root/mynane/main下面创建的)
mkdir -p jenkins-docker
cd jenkins-docker
# 创建数据持久化目录(一定要在jenkins-docker目录下运行哦)
mkdir -p jenkins_home
# 查看当前目录结构
pwd # 应该显示:/root/你的用户名/jenkins-docker
设置正确的目录权限至关重要,这能保证Jenkins容器有足够的权限读写宿主机上的数据卷:
# Jenkins容器内使用UID 1000运行
# 需要给jenkins_home目录正确的权限
sudo chown -R 1000:1000 jenkins_home
# 验证权限
ls -la jenkins_home
接下来,在项目根目录创建核心配置文件docker-compose.yml:
# 使用nano编辑器创建配置文件
vim docker-compose.yml
将以下配置内容粘贴到该文件中。我们选择官方提供的jenkins/jenkins:lts-jdk21镜像,它基于最新的Jenkins长期支持(LTS)版本并运行在Java 21上,兼顾了稳定性和性能。如果你因项目兼容性需要Java 17环境,只需将镜像标签改为jenkins/jenkins:lts-jdk17即可。
version: '3.8'
services:
jenkins:
image: jenkins/jenkins:lts-jdk21
container_name: jenkins
restart: unless-stopped
privileged: true
user: root
ports:
- "8080:8080" # Jenkins Web界面
- "50000:50000" # Jenkins代理通信端口
volumes:
# 持久化Jenkins数据
- ./jenkins_home:/var/jenkins_home
# 允许Jenkins使用主机的Docker
- /var/run/docker.sock:/var/run/docker.sock
# 挂载Docker二进制文件(可选,用于在Jenkins中执行docker命令)
- /usr/bin/docker:/usr/bin/docker
environment:
- JAVA_OPTS=-Duser.timezone=Asia/Shanghai -Dhudson.model.DirectoryBrowserSupport.CSP=
- JENKINS_OPTS=--prefix=/jenkins
networks:
- jenkins-network
networks:
jenkins-network:
driver: bridge
重要说明:
配置文件定义了服务端口映射、数据卷挂载(确保Jenkins配置和插件持久化)以及容器重启策略。保存文件后,使用一条命令即可启动整个Jenkins服务栈:
# 启动容器(后台运行)
docker compose up -d
# 查看容器状态
docker compose ps
# 查看容器日志
docker compose logs -f jenkins
命令执行后,控制台会输出容器启动日志。你应当看到类似下面的信息,表明容器正在启动:
[+] Running 2/2
✔ Network jenkins-docker_jenkins-network Created
✔ Container jenkins Started
启动过程可能需要1-2分钟。你可以使用以下命令实时查看启动日志,监控初始化进度:
#解决方法:是网络原因,修改一下镜像就行
sudo tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": [
"https://x1doswo1.mirror.aliyuncs.com",
"https://docker.1panel.live",
"https://docker.rainbond.cc",
"https://docker.m.daocloud.io",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.nju.edu.cn",
"https://mirror.baidubce.com"
]
}
EOF
当日志中出现类似“Jenkins is fully up and running”的信息时,说明服务已就绪。此时可以按Ctrl+C退出日志跟踪。
Jenkins首次启动时,会生成一个随机的初始管理员密码,并存储在容器内。我们需要获取这个密码以完成后续的解锁操作:
解决方法:sed -i '/^version:/d' docker-compose.yml
耐心等待Jenkins完全启动(通常需要1-2分钟初始化插件和配置),然后获取初始密码:
# 实时查看启动日志
docker compose logs -f jenkins
# 看到以下信息说明启动成功:
# Jenkins is fully up and running
复制终端显示的密码字符串(例如:3f4a6b8c1d2e5f7a9b0c1d2e3f4a5b6c7),稍后使用。
四、 安全与访问:配置防火墙与初始化Jenkins
在通过网络访问Jenkins之前,必须配置服务器的安全策略,这是保护你的CI/CD平台不被未授权访问的关键步骤。
1. 配置服务器防火墙
如果你使用的是Ubuntu系统,默认的防火墙工具是UFW。我们需要开放Jenkins的Web服务端口(默认为8080):
# 方式1:从日志中查看
docker compose logs jenkins | grep -A 5 "initialAdminPassword"
# 方式2:从容器内查看
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
# 方式3:从持久化目录查看
cat jenkins_home/secrets/initialAdminPassword
2. 配置云服务商安全组
如果你的服务器运行在阿里云、腾讯云等云平台上,还需要在云控制台配置安全组规则。以阿里云ECS为例,你需要添加一条入方向规则:
| 端口范围 | 授权对象 | 说明 |
|---|---|---|
| 22/22 | 0.0.0.0/0 | SSH |
| 8080/8080 | 0.0.0.0/0 | Jenkins Web |
| 50000/50000 | 0.0.0.0/0 | Jenkins Agent |
⚠️ 安全警告:规则中的源地址0.0.0.0/0表示允许所有IP访问。在生产环境中,强烈建议将其改为你公司或团队的特定IP地址段,以最小化安全风险。
完成安全配置后,就可以在浏览器中访问并初始化Jenkins了。
步骤1:访问Jenkins
在浏览器地址栏输入你的服务器IP地址和端口号:
# 检查防火墙状态
sudo ufw status
# 如果防火墙未启用,先启用
sudo ufw enable
# 允许SSH(防止被锁在外面!)
sudo ufw allow 22/tcp
# 允许Jenkins Web端口
sudo ufw allow 8080/tcp
# 允许Jenkins代理端口(如果需要)
sudo ufw allow 50000/tcp
# 重新加载防火墙
sudo ufw reload
# 查看规则
sudo ufw status numbered
例如:http://192.168.1.100:8080。
步骤2:解锁Jenkins
首次访问会看到一个“解锁Jenkins”的页面。将之前从容器日志中复制的初始管理员密码粘贴到输入框中,点击“Continue”。
步骤3:安装插件
接下来,Jenkins会建议安装插件。对于新手,选择“Install suggested plugins”(安装推荐插件)是最快捷的方式。安装过程可能需要5-10分钟,取决于你的网络速度。除了推荐插件,对于现代化的CI/CD流水线,我强烈建议后续在插件管理中安装以下扩展:
- Git plugin / GitHub Integration:源代码管理核心。
- Pipeline / Docker Pipeline:定义流水线即代码,是容器化部署自动化的核心。
- Blue Ocean:提供可视化、更直观的流水线编辑和监控界面。
- Kubernetes Plugin:如果你计划将来将构建任务或Jenkins本身部署到Kubernetes (K8s)集群,这个插件必不可少[AFFILIATE_SLOT_2]。
步骤4:创建管理员用户
插件安装完成后,系统会提示你创建第一个管理员用户。请务必使用一个强密码,并填写有效的邮箱地址。
步骤5:配置实例URL
Jenkins URL通常会自动填充,确认无误后保存即可。
步骤6:开始使用
点击“Start using Jenkins”,你将正式进入Jenkins的仪表盘。至此,一个基于Docker容器化部署的Jenkins CI/CD平台已经成功搭建完成!

五、 总结与进阶展望
通过本文的步骤,我们完成了一套基于Java 21和Docker的现代化Jenkins CI/CD平台的部署。我们不仅升级了基础运行环境,还利用Docker Compose实现了Jenkins的容器化部署,确保了环境的一致性和可重复性。同时,我们兼顾了安全配置,为平台的稳定运行打下了基础。
这套方案只是一个起点。接下来,你可以探索更多进阶主题,例如:
- 使用Jenkins Pipeline编写复杂的构建、测试、部署流水线。
- 将构建代理(Agent)也容器化,实现动态伸缩的构建资源池。
- 将整套Jenkins系统(Master和Agents)迁移到Kubernetes上进行编排和管理,实现更高可用性和弹性伸缩。
- 集成SonarQube进行代码质量分析,集成Nexus作为私有制品仓库。
容器化和自动化是云原生时代的基石。掌握Jenkins与Docker的结合,将为你的团队迈向高效的DevOps实践和更复杂的容器编排世界铺平道路。现在,开始创建你的第一个自动化任务吧!
浙公网安备 33010602011771号