如何在GitLab CI/CD流水线中向Docker容器内Web应用发起HTTPS请求?
GitLab CI/CD中Docker容器内Web应用的网络连接问题解决
问题描述
在GitLab CI/CD流水线中部署了依赖Semgrep、Docker Compose的Web应用,尝试通过curl等工具向容器内的https://127.0.0.1:9000发起请求时,出现连接拒绝错误。流水线已成功完成软件部署,但测试步骤无法连通应用。
作业关键日志
$ docker-compose up -d # 省略镜像拉取、构建过程... Creating javavulny ... done $ sleep 10 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fa34b64d241a stackhawk/javavulny:latest "java -Djava.securit…" 10 seconds ago Up 10 seconds 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp javavulny cec9a90873de postgres "docker-entrypoint.s…" 10 seconds ago Up 10 seconds 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp java-github-actions-demo_db_1 $ curl -k https://127.0.0.1:9000 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 curl: (7) Failed to connect to 127.0.0.1 port 9000 after 0 ms: Connection refused
解决方案
1. 确保应用完全启动就绪
日志中仅用sleep 10等待启动,但Spring Boot+数据库的应用初始化可能需要更长时间,直接请求会遇到未就绪的情况。替换固定休眠为动态等待:
# 循环检查端口,超时120秒 timeout=120 start_time=$(date +%s) while ! curl -k --connect-timeout 5 https://127.0.0.1:9000 >/dev/null 2>&1; do current_time=$(date +%s) elapsed=$((current_time - start_time)) if [ $elapsed -ge $timeout ]; then echo "应用启动超时" exit 1 fi echo "等待应用启动...已耗时${elapsed}秒" sleep 5 done
也可以在docker-compose.yml中给javavulny服务添加健康检查,让Docker自动等待应用就绪:
services: javavulny: # 其他配置... healthcheck: test: ["CMD", "curl", "-k", "https://localhost:9000/actuator/health"] interval: 5s timeout: 5s retries: 12
流水线中用docker-compose up -d && docker-compose wait替代sleep 10。
2. 适配GitLab Runner的网络环境
如果Runner使用docker或docker-in-docker执行器,作业容器和应用容器不在同一网络栈,127.0.0.1指向作业容器自身而非应用容器。可以:
- 直接通过容器IP访问:
APP_IP=$(docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' javavulny) curl -k https://$APP_IP:9000 - 让作业容器和应用容器加入同一网络:
在流水线中先创建共享网络,启动应用时指定该网络,后续测试步骤也连接到该网络。
3. 无需修改/etc/hosts
当前应用端口映射为0.0.0.0:9000->9000,说明应用绑定了所有网卡,不需要修改/etc/hosts,上述两种方法即可解决连接问题。
内容的提问来源于stack exchange,提问作者Alex Cohen
相关产品推荐
相关产品推荐

