CI/CD 用于在 aws EC2 中构建和部署 docker 映像的脚本

CI/CD script for build & deploy docker image in aws EC2

我可以使用此 CI/CD 配置构建、推送(到 gitlab 注册表)和部署映像(到 aws EC2)吗?

stages:
  - build
  - deploy

build:
  # Use the official docker image.

  image: docker:latest
  stage: build
  services:
    - docker:dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
  # Default branch leaves tag empty (= latest tag)
  # All other branches are tagged with the escaped branch name (commit ref slug)
  script:
    - |
      if [[ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]]; then
        tag=""
        echo "Running on default branch '$CI_DEFAULT_BRANCH': tag = 'latest'"
      else
        tag=":$CI_COMMIT_REF_SLUG"
        echo "Running on branch '$CI_COMMIT_BRANCH': tag = $tag"
      fi
    - docker build --pull -t "$CI_REGISTRY_IMAGE${tag}" .
    - docker push "$CI_REGISTRY_IMAGE${tag}"
  # Run this job in a branch where a Dockerfile exists

deploy:
  stage: deploy
  before_script:
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
  script:
    - ssh -o StrictHostKeyChecking=no ubuntu@18.0.0.82 "sudo docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY; sudo docker pull $CI_REGISTRY_IMAGE${tag}; cd /home/crud_app; sudo docker-compose up -d"
  after_script:
    - sudo docker logout

  rules:
    - if: $CI_COMMIT_BRANCH
      exists:
        - Dockerfile

脚本构建成功后,部署失败。

(构建成功)

(部署失败)

必须构建配置并部署映像

有几个错误,但整个流水线看起来不错。

  1. 没有代理 运行
  2. 就不能使用 ssh-add
  3. 如果之后明确忽略将存储在 known_hosts 下的密钥,为什么要手动创建 .ssh 文件夹?
  4. 使用 StrictHostKeyChecking=no 很危险,完全不推荐。

before_script 添加以下内容:

before_script:
    - eval `ssh-agent`
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - ssh-keyscan -H 18.0.0.82 >> ~/.ssh/known_hosts

此外,不要在 ubuntu 用户上使用 sudo,最好将其添加到 docker 组或通过 SSH 连接到 [=21] 中的用户=]组.


如果您的 EC2 实例中还没有 docker 组,现在是配置它的好时机:

访问您的 EC2 实例并创建 docker 组:

$ sudo groupadd docker

ubuntu 用户添加到 docker 组:

$ sudo usermod -aG docker ubuntu

现在将您的 script 更改为:

script:
    - echo $CI_REGISTRY_PASSWORD > docker_password
    - scp docker_password ubuntu@18.0.0.82:~/tmp/docker_password
    - ssh ubuntu@18.0.0.82 "cat ~/tmp/docker_password | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY; docker pull $CI_REGISTRY_IMAGE${tag}; cd /home/crud_app; docker-compose up -d; docker logout; rm -f ~/tmp/docker_password"

此外,请记住,在 after_script 中,您不在 EC2 实例中,而是在运行器图像中,因此您不需要 logout,但最好杀死SSH 代理。

最终任务

deploy:
  stage: deploy
  before_script:
    - eval `ssh-agent`
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - ssh-keyscan -H 18.0.0.82 >> ~/.ssh/known_hosts
  script:
    - echo $CI_REGISTRY_PASSWORD > docker_password
    - scp docker_password ubuntu@18.0.0.82:~/tmp/docker_password
    - ssh ubuntu@18.0.0.82 "cat ~/tmp/docker_password | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY; docker pull $CI_REGISTRY_IMAGE${tag}; cd /home/crud_app; docker-compose up -d; docker logout; rm -f ~/tmp/docker_password"
  after_script:
    - kill $SSH_AGENT_PID
    - rm docker_password
  rules:
    - if: $CI_COMMIT_BRANCH
      exists:
        - Dockerfile