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
相关产品推荐
相关产品推荐

