GitLab EE无法连接Docker容器中PlantUML的问题排查
问题描述
我在Ubuntu 20.04上安装并配置了GitLab EE(Omnibus)服务器,按照官方文档用以下命令启动了Docker容器中的PlantUML:
docker run -d --name plantuml -p 8084:8080 plantuml/plantuml-server:tomcat
随后配置了/etc/gitlab/gitlab.rb文件,添加SSL环境下的重定向规则:
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n proxy_cache off; \n proxy_pass http://plantuml:8080/; \n}\n"
在GitLab管理面板的「设置→通用→PlantUML」中,我尝试了两种PlantUML URL配置:
- 配置为
https://HOSTNAME:8084/-/plantuml,浏览器访问时提示「无法提供安全连接(ERR_SSL_PROTOCOL_ERROR)」; - 配置为
https://HOSTNAME/-/plantuml,浏览器访问时出现502错误,提示「GitLab响应超时」。
两种配置下,通过gitlab-ctl tail查看日志均出现以下错误:
[crit] *901 SSL_do_handshake() failed (SSL: error:141CF06C:SSL routines:tls_parse_ctos_key_share:bad key share) while SSL handshaking, client: CLIENT_IP, server: 0.0.0.0:443 [error] 1123593#0: *4 connect() failed (113: No route to host) while connecting to upstream
请问哪种配置方式正确,我是否遗漏了相关配置?
问题分析与解决方案
1. 两种配置的对错判断
- 第一种配置
https://HOSTNAME:8084/-/plantuml完全错误:你启动的PlantUML容器仅映射了HTTP协议的8084端口,未配置SSL证书,浏览器强制用HTTPS访问必然触发SSL协议错误。 - 第二种配置
https://HOSTNAME/-/plantuml是正确的方向:通过GitLab自带的Nginx反向代理转发请求,避免直接暴露PlantUML的非安全端口,但当前502错误是因为GitLab的Nginx进程无法连接到PlantUML容器。
2. 核心问题:Nginx无法连接PlantUML容器的原因
日志中的connect() failed (113: No route to host)明确指向:GitLab的Nginx进程(宿主机上的进程,非容器化)无法通过plantuml这个容器名解析到对应IP——默认Docker桥接网络中,宿主机进程不能直接用容器名访问容器。
3. 修复步骤
步骤1:修正GitLab Nginx反向代理配置
编辑/etc/gitlab/gitlab.rb,将proxy_pass的目标地址替换为宿主机IP(比如127.0.0.1,对应容器映射的8084端口):
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n proxy_cache off; \n proxy_pass http://127.0.0.1:8084/; \n}\n"
注:如果宿主机有多个IP,需使用容器能访问到的宿主机内网/公网IP。
步骤2:添加代理头(可选但推荐)
为了让PlantUML服务器正确处理请求来源,建议在location块中补充代理头:
nginx['custom_gitlab_server_config'] = "location /-/plantuml/ { \n proxy_cache off; \n proxy_pass http://127.0.0.1:8084/; \n proxy_set_header Host $host; \n proxy_set_header X-Real-IP $remote_addr; \n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \n proxy_set_header X-Forwarded-Proto $scheme; \n}\n"
步骤3:让配置生效并重启服务
执行以下命令更新GitLab配置并重启Nginx:
gitlab-ctl reconfigure gitlab-ctl restart nginx
步骤4:配置GitLab管理面板的PlantUML URL
在「设置→通用→PlantUML」中,配置为:
https://HOSTNAME/-/plantuml/
注:末尾的斜杠必须保留,与Nginx配置的location路径匹配。
4. 关于SSL握手错误的额外修复
日志中的SSL_do_handshake() failed错误与PlantUML无关,是客户端TLS版本与GitLab SSL配置不兼容导致的,可在gitlab.rb中添加TLS版本限制修复:
nginx['ssl_protocols'] = "TLSv1.2 TLSv1.3" nginx['ssl_ciphers'] = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
添加后同样执行gitlab-ctl reconfigure和gitlab-ctl restart nginx生效。
内容的提问来源于stack exchange,提问作者Alex M.

