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

GitLab CI使用容器仓库时提示docker: not found问题求助

GitLab CI执行docker命令提示"docker: not found"的原因分析与解决方案

错误原因分析

  1. CI执行环境未预装Docker CLI
    从错误日志可见,build_image任务使用Docker executor,默认拉取alpine:3.14作为执行环境镜像,该基础镜像未包含Docker CLI工具,因此执行docker build时会提示命令未找到。你在应用Dockerfile中添加的RUN apk add docker-cli是给最终构建的应用镜像安装Docker,和CI任务的执行环境完全无关。

  2. 变量配置存在误解
    你标注的变量对应关系错误:

    • $CI_REGISTRY_IMAGE是GitLab自动生成的镜像仓库地址(如registry.gitlab.com/komorebi-cqd/mynodeapp-cicd-project),不是完整的docker build命令
    • $CI_REGISTRY是仓库域名(如registry.gitlab.com),不是docker push命令
      当前.gitlab-ci.yml中的变量定义本身没问题,但你的理解存在偏差。
  3. Docker executor的隔离性限制
    即使服务器本地安装了Docker,Docker executor默认会在独立容器中运行CI任务,容器无法直接访问主机的Docker命令,必须通过特定配置打破隔离。


具体解决方案

方案一:使用Docker-in-Docker(DinD)服务(官方推荐)

通过启动DinD服务,让CI任务的执行容器拥有完整的Docker环境,这是GitLab CI构建容器镜像的标准方案。

步骤1:修改.gitlab-ci.yml

更新build_image和push_image任务配置:

build_image:
  stage: build
  tags: 
    - remoteone
  image: docker:24.0.6  # 使用包含Docker CLI的官方镜像
  services:
    - docker:24.0.6-dind  # 启动DinD服务
  variables:
    DOCKER_HOST: tcp://docker:2376
    DOCKER_TLS_CERTDIR: "/certs"
    DOCKER_TLS_VERIFY: 1
    DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
  before_script:
    - echo "Docker registry url is $CI_REGISTRY"
    - echo "Docker registry username is $CI_REGISTRY_USER"
    - echo "Docker registry repo is $CI_REGISTRY_IMAGE"
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_NAME .

push_image:
  stage: build
  needs: 
    - build_image
  tags:
    - remoteone
  image: docker:24.0.6
  services:
    - docker:24.0.6-dind
  variables:
    DOCKER_HOST: tcp://docker:2376
    DOCKER_TLS_CERTDIR: "/certs"
    DOCKER_TLS_VERIFY: 1
    DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
  script: 
    - docker push $IMAGE_NAME

步骤2:开启Runner特权模式

DinD服务需要特权权限才能运行,修改Runner配置文件(通常为/etc/gitlab-runner/config.toml):

[[runners]]
  name = "one-docker-runner"
  url = "你的GitLab实例地址"
  token = "fAyvKeBR"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "alpine:3.14"
    privileged = true  # 必须开启特权模式
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0

步骤3:重启Runner

sudo gitlab-runner restart

方案二:改用Shell Executor

直接让CI任务在服务器本地执行,使用主机已安装的Docker环境,适合不需要容器化执行环境的场景。

步骤1:修改Runner配置

更新config.toml切换执行器:

[[runners]]
  name = "one-docker-runner"
  url = "你的GitLab实例地址"
  token = "fAyvKeBR"
  executor = "shell"  # 改为shell执行器
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

步骤2:重启Runner

sudo gitlab-runner restart

说明

无需修改.gitlab-ci.yml中的build_image和push_image任务,任务会直接调用主机的Docker命令执行。


方案三:挂载主机Docker Socket(不推荐,存在安全风险)

让CI执行容器共享主机的Docker服务,仅适合测试环境,因为会打破容器隔离性带来安全隐患。

修改.gitlab-ci.yml

build_image:
  stage: build
  tags: 
    - remoteone
  image: alpine:3.14
  variables:
    DOCKER_HOST: unix:///var/run/docker.sock
  before_script:
    - apk add --no-cache docker-cli  # 在执行镜像中安装Docker CLI
    - echo "Docker registry url is $CI_REGISTRY"
    - echo "Docker registry username is $CI_REGISTRY_USER"
    - echo "Docker registry repo is $CI_REGISTRY_IMAGE"
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_NAME .
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock  # 挂载主机Docker Socket

修改Runner配置

允许挂载主机目录:

[[runners]]
  name = "one-docker-runner"
  url = "你的GitLab实例地址"
  token = "fAyvKeBR"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "alpine:3.14"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
    shm_size = 0

内容的提问来源于stack exchange,提问作者qiaoda chen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:15:40