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

GitLab CI/CD部署ASP.NET Core 6 Docker镜像报错求助

解决GitLab流水线中docker: command not found错误及部署阶段问题

错误原因

你使用的GitLab Runner构建镜像中未预装Docker环境,导致执行docker命令时找不到程序。下面提供两种可行的解决方式,同时覆盖部署阶段的适配方案。

方案1:使用Docker-in-Docker(DinD)官方镜像(推荐)

GitLab官方提供了预装Docker环境的镜像,配合DinD服务可以直接在流水线中使用Docker命令,无需手动安装。

示例流水线配置:

stages:
  - build
  - docker-build
  - deploy

# ASP.NET Core 6 编译阶段
build:
  stage: build
  image: mcr.microsoft.com/dotnet/sdk:6.0
  script:
    - dotnet restore
    - dotnet build --configuration Release --no-restore
    - dotnet publish --configuration Release --no-build -o ./publish

# Docker镜像构建&推送阶段
docker-build:
  stage: docker-build
  image: docker:latest
  services:
    - docker:dind  # 启动DinD服务作为Docker daemon
  variables:
    DOCKER_HOST: tcp://docker:2375  # 指定Docker daemon地址
    DOCKER_DRIVER: overlay2
    CI_REGISTRY: $CI_REGISTRY  # GitLab自带的容器仓库地址变量
    CI_REGISTRY_USER: $CI_REGISTRY_USER  # GitLab自动提供的仓库用户名
    CI_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD  # GitLab自动提供的仓库密码
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  dependencies:
    - build  # 依赖编译阶段的产物

# 部署阶段(以部署到Runner所在服务器为例)
deploy:
  stage: deploy
  image: docker:latest
  services:
    - docker:dind
  variables:
    DOCKER_HOST: tcp://docker:2375
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
    - docker stop aspnet-core-app || true  # 容器不存在时忽略错误
    - docker rm aspnet-core-app || true
    - docker run -d --name aspnet-core-app -p 80:80 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

关键配置说明

  • image: docker:latest:使用官方Docker镜像,内置docker命令
  • services: - docker:dind:启动DinD服务,提供Docker daemon运行环境
  • 变量DOCKER_HOST:告诉流水线中的Docker客户端连接到DinD服务的daemon
  • 需确保你的GitLab Runner配置了privileged: true(在runner的config.toml中[runners.docker]下添加该配置,然后重启runner),否则DinD服务无法正常启动。

方案2:在现有镜像中手动安装Docker

如果不想更换编译/构建镜像(比如继续使用.NET SDK 6镜像),可以在before_script中手动安装Docker环境。

示例配置(基于Debian系的.NET SDK镜像):

docker-build:
  stage: docker-build
  image: mcr.microsoft.com/dotnet/sdk:6.0
  before_script:
    # 安装Docker依赖及程序
    - apt-get update && apt-get install -y --no-install-recommends docker.io
    # 启动Docker daemon
    - service docker start
    # 登录GitLab容器仓库
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  dependencies:
    - build

注意事项

  • 该方法仅适用于基于Debian/Ubuntu的镜像(.NET SDK镜像满足),如果是其他系统镜像需调整安装命令
  • 同样需要Runner配置privileged: true,否则无法启动Docker daemon

部署阶段避免失败的适配方案

如果部署阶段需要操作Docker(拉取镜像、启动容器),可以参考以下两种场景:

场景1:部署到Runner所在服务器

直接复用方案1中的DinD镜像配置即可,和构建阶段逻辑一致。

场景2:部署到远程服务器

通过SSH连接远程服务器执行Docker命令,需要提前在GitLab项目变量中配置:

  • SSH_PRIVATE_KEY:远程服务器的SSH私钥(需无密码)
  • SSH_KNOWN_HOSTS:远程服务器的SSH公钥指纹(避免首次连接的确认提示)

示例配置:

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    # 安装SSH客户端和Docker
    - apk add --no-cache openssh-client docker
    # 启动SSH代理并添加私钥
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    # 配置SSH信任主机
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts
  script:
    # 远程执行Docker命令
    - ssh user@your-server-ip "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY"
    - ssh user@your-server-ip "docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
    - ssh user@your-server-ip "docker stop aspnet-core-app || true && docker rm aspnet-core-app || true"
    - ssh user@your-server-ip "docker run -d --name aspnet-core-app -p 80:80 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:48:23