英文:
CI/CD Pipeline config for GitLab to publish ASP.NET Core 6 web app in docker container
问题
需要先说明,我是一个CI/CD和Gitlab的初学者。话虽如此,我已经设法(使用来自网络的示例)拼凑出一个“几乎”工作的流水线配置:
image: mcr.microsoft.com/dotnet/sdk:6.0
variables:
OBJECTS_DIRECTORY: 'obj'
NUGET_PACKAGES_DIRECTORY: '.nuget'
SOURCE_CODE_PATH: '*/*/'
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
stages:
- build
- test
- docker
- deploy
cache:
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
paths:
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/project.assets.json'
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/*.csproj.nuget.*'
- '$NUGET_PACKAGES_DIRECTORY'
policy: pull-push
before_script:
- 'dotnet restore --packages $NUGET_PACKAGES_DIRECTORY'
build:
stage: build
script:
- 'dotnet build --no-restore'
tests:
stage: test
script:
- 'dotnet test --no-restore'
docker:
stage: docker
image: docker:latest
services:
- docker:18.09.7-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
only:
- main
before_script:
- apt-get update
- apt-get install docker -y
script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
deploy:
stage: deploy
image: alpine:latest
services:
- docker:dind
script:
- chmod og= $ID_RSA
- apk update && apk add openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f atlas-portal-2.0 || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name atlas-portal-2.0 $TAG_COMMIT"
environment:
name: production
only:
- main
当我运行此流水线时,它成功进入“docker”阶段,我希望在其中构建并存储Docker镜像到Gitlab容器注册表。但是,我收到以下错误消息:
"/bin/bash: line 149: docker: command not found"
我知道我需要在将要构建Docker镜像以存储在Gitlab的Docker镜像中“安装”Docker,但我不确定该如何操作。
一旦我解决了这个“docker”阶段,我相信“deploy”阶段也会失败。我是个新手...
英文:
I need to start by saying that I am a beginner with CI/CD and with Gitlab. That being said, I have managed to cobble together (using examples from the web) this "almost" working pipeline configuration:
image: mcr.microsoft.com/dotnet/sdk:6.0
variables:
OBJECTS_DIRECTORY: 'obj'
NUGET_PACKAGES_DIRECTORY: '.nuget'
SOURCE_CODE_PATH: '*/*/'
TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
stages:
- build
- test
- docker
- deploy
cache:
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
paths:
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/project.assets.json'
- '$SOURCE_CODE_PATH$OBJECTS_DIRECTORY/*.csproj.nuget.*'
- '$NUGET_PACKAGES_DIRECTORY'
policy: pull-push
before_script:
- 'dotnet restore --packages $NUGET_PACKAGES_DIRECTORY'
build:
stage: build
script:
- 'dotnet build --no-restore'
tests:
stage: test
script:
- 'dotnet test --no-restore'
docker:
stage: docker
image: docker:latest
services:
- docker:18.09.7-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
only:
- main
before_script:
- apt-get update
- apt-get install docker -y
script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
deploy:
stage: deploy
image: alpine:latest
services:
- docker:dind
script:
- chmod og= $ID_RSA
- apk update && apk add openssh-client
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f atlas-portal-2.0 || true"
- ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name atlas-portal-2.0 $TAG_COMMIT"
environment:
name: production
only:
- main
When I run this pipeline, it successfully gets to the “docker” stage where I hope to build and store the docker image in the gitlab container registry. Instead I get the following error:
> "/bin/bash: line 149: docker: command not found"
I know that somehow I need to “install” docker in the docker image that is going to be building the docker image to store in gitlab, but I am not sure how to go about doing that.
And once I get past this “docker” stage I feel confident that the “deploy” stage is going to fail too. I am a newbie...
答案1
得分: 1
你的 docker
任务应该如下所示:
docker:
stage: docker
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
only:
- main
before_script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
script:
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
由于你已经使用了一个安装了 docker
的镜像,不需要运行 apt-get update && apt-get install docker -y
,只需运行命令即可。
另外,建议为每个任务定义 image
值,除非你打算在所有任务中都使用相同的镜像。因此,你在文件顶部定义的用于使用 dotnet
的镜像最好放在 build
和 tests
任务中。如果不想重复代码,你可以使用变量来重用该值,例如:
variables:
DOTNET_IMAGE: mcr.microsoft.com/dotnet/sdk:6.0
...
build:
image: $DOTNET_IMAGE
...
tests:
image: $DOTNET_IMAGE
英文:
Your docker
job should look like this instead:
docker:
stage: docker
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
only:
- main
before_script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
script:
- docker build --tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" --tag "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
- docker push "$CI_REGISTRY_IMAGE:latest"
As you're already using an image that has docker
installed, there is no need to run apt-get update && apt-get install docker -y
, just run the command and that will make up for it.
Also another piece of advice, it'd be best for you to define the image
value for each job unless you will use the same for all of them. So the one you have defined at the top of the file to use dotnet
would be better placed at build
and tests
jobs. If you don't want to repeat code you can use variables to reuse the value, e.g:
variables:
DOTNET_IMAGE: mcr.microsoft.com/dotnet/sdk:6.0
...
build:
image: $DOTNET_IMAGE
...
tests:
image: $DOTNET_IMAGE
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论