You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab Pipeline运行Spring Boot集成测试遇Docker连接错误求助

解决GitLab Pipeline中Docker Compose连接失败问题

我开发了一个Spring Boot电影API应用,运行集成测试需要mongodb、rabbitmq以及docker-compose-test.yml中定义的其他服务处于运行状态。编写了对应的.gitlab-ci.yml配置文件,尝试过拆分任务和合并任务两种执行方式,但均运行失败,出现Docker连接相关的FileNotFoundError错误,需要实现在GitLab Pipeline中先启动Docker Compose服务,再执行mvn test命令。

相关配置文件

docker-compose-test.yml

version: '3.1'
services:
  gateway-app:
    image: 'danielmarandici/movies_gateway:tagname'
    ports:
      - "8088:8088"
    environment:
      eureka.instance.preferIpAddress: 'true'
      eureka.client.serviceUrl.defaultZone: http://eurekaserver:8761/eureka/
      eureka.host: eurekaserver
    networks:
      - ms-network
  eurekaserver:
    image: 'danielmarandici/eureka_server:tagname'
    environment:
      eureka.client.registerWithEureka: 'false'
      eureka.client.fetchRegistry: 'false'
      eureka.instance.preferIpAddress: 'true'
      eureka.client.serviceUrl.defaultZone: http://eurekaserver:8761/eureka/
    ports:
      - 8761:8761
    networks:
      - ms-network
    depends_on:
      - rabbitmq
  mongodb:
    image: mongo
    ports:
      - '27017:27017'
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: root
    networks:
      - ms-network
  rabbitmq:
    image: rabbitmq:3.10.7-management
    hostname: rabbitmq
    restart: always
    environment:
      - RABBITMQ_DEFAULT_USER=rmuser
      - RABBITMQ_DEFAULT_PASS=rmpassword
      - RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS=-rabbit log_levels [{connection,error},{default,error}] disk_free_limit 2147483648
    volumes:
      - ~/volumes/cnas/rabbitmq:/var/lib/rabbitmq
    ports:
      - '15673:15673'
      - '5672:5672'
    networks:
      - ms-network

networks:
  ms-network:
    driver: bridge

.gitlab-ci.yml(原配置)

variables:
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"

stages:
  - build
  - build_and_test
  # - startneed
  # - test

build:
  image: maven:latest
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile


# startneed:
#   image: docker/compose:latest
#   services:
#     - docker:dind
#   stage: startneed
#   script:
#     - docker-compose -f docker-compose-test.yml up -d

# test:
#   image: maven:latest
#   stage: test
#   script:
#     - mvn $MAVEN_CLI_OPTS test

before_script:
  - apt-get update
  - apt-get install -y docker.io docker-compose

build_and_test:
  stage: build_and_test
  image: maven:latest
  script:
    - echo "Running Docker Compose services..."
    - docker-compose -f docker-compose-test.yml up -d
    - echo "Running Maven tests..."
    - mvn $MAVEN_CLI_OPTS test
    - echo "Stopping Docker Compose services..."
    - docker-compose down

错误信息

$ docker-compose -f docker-compose-test.yml up -d
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 700, in urlopen
    httplib_response = self._make_request(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 395, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.10/http/client.py", line 1283, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1329, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1278, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.10/http/client.py", line 1038, in _send_output
    self.send(msg)
  File "/usr/lib/python3.10/http/client.py", line 976, in send
    self.connect()
  File "/usr/lib/python3/dist-packages/docker/transport/unixconn.py", line 30, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 756, in urlopen
    retries = retries.increment(
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 532, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/lib/python3/dist-packages/six.py", line 718, in reraise
    raise value.with_traceback(tb)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 700, in urlopen
    httplib_response = self._make_request(
....

  File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 152, in get_project
    client = get_client(
  File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 41, in get_client
    client = docker_client(
  File "/usr/lib/python3/dist-packages/compose/cli/docker_client.py", line 170, in docker_client
    client = APIClient(use_ssh_client=not use_paramiko_ssh, **kwargs)
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 197, in __init__
    self._version = self._retrieve_server_version()
  File "/usr/lib/python3/dist-packages/docker/api/client.py", line 221, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 1

解决方案

错误根源是GitLab Runner的job中没有配置Docker-in-Docker(DinD)服务,导致docker客户端无法连接到docker守护进程。调整配置如下:

1. 修改.gitlab-ci.yml配置

使用DinD服务,并设置必要的环境变量让docker客户端能正确连接到守护进程,同时添加服务启动等待逻辑:

variables:
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version"
  # Docker DinD 必要环境变量
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"
  DOCKER_TLS_VERIFY: 1
  DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"

stages:
  - build
  - build_and_test

build:
  image: maven:latest
  stage: build
  script:
    - mvn $MAVEN_CLI_OPTS compile

build_and_test:
  stage: build_and_test
  image: maven:latest
  # 启用Docker-in-Docker服务
  services:
    - docker:dind
  before_script:
    # 安装docker-compose
    - apt-get update && apt-get install -y docker-compose
    # 等待Docker守护进程就绪
    - until docker info; do sleep 1; done
  script:
    - echo "启动Docker Compose服务..."
    - docker-compose -f docker-compose-test.yml up -d
    # 等待依赖服务完全启动(根据实际服务启动时间调整时长)
    - sleep 30
    - echo "执行Maven测试..."
    - mvn $MAVEN_CLI_OPTS test
    - echo "停止Docker Compose服务..."
    - docker-compose down

2. 关键调整说明

  • 启用DinD服务:在build_and_test job中添加services: - docker:dind,提供独立的Docker守护进程环境。
  • 环境变量配置:设置DOCKER_HOST等变量,让docker客户端通过TCP连接到DinD服务的守护进程,而非默认的Unix套接字(这是原错误的核心原因)。
  • 服务就绪等待:添加until docker info; do sleep 1; done确保Docker守护进程启动完成,再执行后续命令;添加sleep 30(或更精准的健康检查)确保mongodb、rabbitmq等服务完全就绪后再执行测试。
  • 简化依赖安装:合并apt-get命令,减少不必要的分层。

3. 额外优化建议

  • 健康检查替代sleep:在docker-compose-test.yml中为mongodb、rabbitmq等服务添加healthcheck配置,然后在CI脚本中使用docker-compose up --wait等待服务健康,比固定sleep更可靠。例如给mongodb添加:
    mongodb:
      image: mongo
      ports:
        - '27017:27017'
      environment:
        MONGO_INITDB_ROOT_USERNAME: root
        MONGO_INITDB_ROOT_PASSWORD: root
      networks:
        - ms-network
      healthcheck:
        test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
        interval: 10s
        timeout: 5s
        retries: 5
    
    然后CI脚本中替换sleep 30为docker-compose -f docker-compose-test.yml up --wait。
  • 镜像版本固定:避免使用latest标签,固定maven、docker、rabbitmq等镜像的具体版本,提升CI执行的稳定性。

内容的提问来源于stack exchange,提问作者S H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 07:45:55