CI/CD Pipeline配置用于在GitLab中发布ASP.NET Core 6 Web应用程序到Docker容器中。

huangapple go评论65阅读模式
英文:

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 的镜像最好放在 buildtests 任务中。如果不想重复代码,你可以使用变量来重用该值,例如:

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

huangapple
  • 本文由 发表于 2023年2月23日 22:11:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75545950.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定