GitLab多作业无法共享Docker容器的原因咨询
GitLab CI中测试作业无法访问Build作业启动的Docker容器的原因及解决办法
问题描述
我们有一个依赖Postgres Docker镜像的Python项目,本地启动Docker容器后应用运行正常。但在GitLab中配置了两个作业(一个启动Docker容器,一个运行Python脚本),依赖第一个作业的第二个作业执行失败,请问第二个作业无法访问Docker容器的原因是什么?
用户提供的.gitlab-ci.yml配置:
stages: - build - test build: image: docker/compose:latest services: - docker:dind script: - docker-compose down --v - docker-compose up -d test: image: python:3.8 needs: [build] variables: POETRY_VERSION: "1.1.15" POETRY_CORE_VERSION: "1.0.8" script: - python --version - POETRY_VIRTUALENVS_IN_PROJECT=true - pip install poetry==${POETRY_VERSION} poetry-core==${POETRY_CORE_VERSION} - poetry install --no-interaction --no-ansi - poetry run pytest
核心原因
GitLab CI的每个作业都运行在完全隔离的Runner执行环境中,作业之间不会共享任何容器、网络或文件系统资源:
build作业启动的Postgres容器,仅存在于build作业对应的Runner实例的Docker环境(由docker:dind服务提供)里。test作业虽然通过needs: [build]保证在build之后执行,但它会在全新的Runner实例中启动,和build作业的环境完全独立,自然无法访问到build里启动的容器。needs关键字仅控制作业的执行顺序,不会实现环境或资源的共享。
可行的解决方案
方案1:将容器启动与测试合并到同一个作业
把启动容器和运行测试的步骤放在同一个作业里,让两者共享同一个Docker环境:
stages: - test test: image: docker/compose:latest services: - docker:dind variables: POETRY_VERSION: "1.1.15" POETRY_CORE_VERSION: "1.0.8" script: - docker-compose down --v - docker-compose up -d # 等待Postgres服务就绪(替换为你的容器名和数据库用户) - until docker exec my-postgres-container pg_isready -U db-user; do sleep 2; done # 安装Python依赖 - apt-get update && apt-get install -y python3 python3-pip - POETRY_VIRTUALENVS_IN_PROJECT=true - pip install poetry==${POETRY_VERSION} poetry-core==${POETRY_CORE_VERSION} - poetry install --no-interaction --no-ansi - poetry run pytest
方案2:使用GitLab CI内置的Postgres服务
直接利用GitLab CI的services配置启动Postgres,无需手动管理Docker容器,这是更简洁的官方推荐方式:
stages: - test test: image: python:3.8 services: - name: postgres:13 alias: postgres variables: POETRY_VERSION: "1.1.15" POETRY_CORE_VERSION: "1.0.8" # GitLab Postgres服务默认环境变量 POSTGRES_USER: test_user POSTGRES_PASSWORD: test_pass POSTGRES_DB: test_db # 应用连接数据库的地址(使用服务别名) DATABASE_URL: postgresql://test_user:test_pass@postgres:5432/test_db script: - python --version - POETRY_VIRTUALENVS_IN_PROJECT=true - pip install poetry==${POETRY_VERSION} poetry-core==${POETRY_CORE_VERSION} - poetry install --no-interaction --no-ansi # 等待Postgres就绪 - apt-get update && apt-get install -y wait-for-it - wait-for-it postgres:5432 -t 30 - poetry run pytest
内容的提问来源于stack exchange,提问作者Prashant kamble
相关产品推荐
相关产品推荐

