Docker容器内Jenkins构建镜像后,如何在宿主机触发部署?
一、挂载Docker套接字(最直接方案)
原理
Docker套接字/var/run/docker.sock是宿主机Docker守护进程(Docker daemon)的通信接口。把这个套接字挂载到Jenkins容器内部后,容器里执行的docker、docker-compose命令会直接调用宿主机的Docker daemon,效果等同于在宿主机本地执行命令。
操作步骤
启动Jenkins时挂载必要资源
若未启动Jenkins,启动命令追加挂载参数:docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /var/run/docker.sock:/var/run/docker.sock \ # 挂载Docker套接字核心参数 -v /usr/bin/docker:/usr/bin/docker \ # 挂载宿主机docker二进制(若Jenkins镜像未预装) -v /usr/bin/docker-compose:/usr/bin/docker-compose \ # 挂载宿主机docker-compose(若镜像未预装) -v jenkins_home:/var/jenkins_home \ jenkins/jenkins:lts若Jenkins镜像已内置docker和docker-compose,后两个挂载参数可省略。
解决权限问题
默认容器内的jenkins用户无docker.sock访问权限,会触发权限报错,可二选一处理:- 启动容器时加
--user root(简单但安全性弱,不推荐生产环境) - 宿主机将jenkins用户(容器内UID通常为1000)加入docker组:
操作后重启Jenkins容器生效。sudo usermod -aG docker jenkins
- 启动容器时加
流水线中执行部署命令
在Jenkins流水线的steps阶段直接编写docker-compose命令即可,示例:stage('Deploy to Host') { steps { sh 'docker-compose -f /container/path/to/docker-compose.yml up -d' } }注:需确保Jenkins容器能访问到
docker-compose.yml,可将宿主机配置文件所在目录挂载到容器内,比如追加参数-v /host/path/to/compose:/container/path/to/compose。
二、通过SSH远程执行(更安全的生产级方案)
原理
借助Jenkins的SSH插件,以有权限的用户身份远程连接宿主机,执行docker-compose命令。这种方式无需暴露Docker套接字,权限隔离更严谨,适合生产环境。
操作步骤
安装Jenkins SSH插件
进入Jenkins「插件管理」,搜索并安装「SSH Pipeline Steps」插件。配置宿主机SSH访问
- 在宿主机创建拥有Docker权限的用户(或给现有用户添加权限):
sudo usermod -aG docker deploy_user - 为该用户配置SSH密钥登录,将公钥写入宿主机
~/.ssh/authorized_keys,避免密码登录的安全风险。
- 在宿主机创建拥有Docker权限的用户(或给现有用户添加权限):
在Jenkins中配置SSH服务器
进入Jenkins「系统管理」→「系统配置」,找到「SSH Servers」,添加宿主机连接信息:- 名称:自定义(如「Host-Prod」)
- 主机名:宿主机IP或域名
- 端口:默认22
- 用户名:上述创建的
deploy_user - 认证方式:选择「SSH密钥」,上传对应私钥。
流水线中执行远程命令
在流水线里通过sshCommand调用远程部署命令,示例:stage('Deploy to Host') { steps { sshCommand( remote: 'Host-Prod', command: 'cd /host/path/to/compose && docker-compose up -d' ) } }
关于你提到的Docker网络IP方式
这种方式需开启宿主机Docker daemon的远程访问,存在明显安全隐患和维护成本,不推荐使用:
- 需修改宿主机
/etc/docker/daemon.json,添加"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"],重启Docker daemon生效 - 还要开放宿主机2375端口,易被未授权访问;且宿主机IP变更后需重新配置,维护繁琐
内容的提问来源于stack exchange,提问作者Legna

