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
脚本构建成功后,部署失败。
(构建成功)
(部署失败)
必须构建配置并部署映像
有几个错误,但整个流水线看起来不错。
- 没有代理 运行
就不能使用 ssh-add
- 如果之后明确忽略将存储在
known_hosts
下的密钥,为什么要手动创建 .ssh 文件夹?
- 使用
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
我可以使用此 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
脚本构建成功后,部署失败。
(构建成功)
(部署失败)
必须构建配置并部署映像
有几个错误,但整个流水线看起来不错。
- 没有代理 运行 就不能使用
- 如果之后明确忽略将存储在
known_hosts
下的密钥,为什么要手动创建 .ssh 文件夹? - 使用
StrictHostKeyChecking=no
很危险,完全不推荐。
ssh-add
在 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