github ci/cd pipeline 的实践
这个网站的 cicd 使用了 github 的 action 功能, action 的脚本如下
-
ssh-keyscan 之所以使用 ssh-keyscan 是因为在 github 的 action 中,没有默认的 known_hosts 文件,所以需要手动添加,避免报错
-
rsync rsync 是用来上传文件的,使用 ssh 协议,将本地的文件上传到远程服务器
-
secrets secrets 是用来存储敏感信息的,比如 ssh 的密码,私钥等,这些信息在 github 的 action 中是保密的,不会泄露
name: CI/CD Pipeline
on:
push:
branches:
- main
env:
IMAGE_NAME: my-cool-app
CONTAINER_NAME: cool
PORT: 30088
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build Docker image
run: |
docker build -t ${{ env.IMAGE_NAME }}:latest .
- name: Save Docker image as tarball
run: |
docker save -o ${{ env.IMAGE_NAME }}-latest.tar ${{ env.IMAGE_NAME }}:latest
- name: Compress and save Docker image as tarball
run: |
if [ -f ${{ env.IMAGE_NAME }}-latest.tar.gz ]; then
rm -f ${{ env.IMAGE_NAME }}-latest.tar.gz
fi
echo "before compress"
ls -alh
gzip ${{ env.IMAGE_NAME }}-latest.tar
echo "after compress"
ls -alh
- name: Upload compressed tarball via SCP
run: |
sudo apt-get update
sudo apt-get install -y sshpass rsync
mkdir -p ~/.ssh
# Add remote server's public key to known_hosts
ssh-keyscan ${{ secrets.PRODUCTION_SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Upload file via SCP
run: |
sshpass -p ${{ secrets.PRODUCTION_SERVER_PASSWORD }} rsync -avz -e ssh ${{ env.IMAGE_NAME }}-latest.tar.gz ${{ secrets.PRODUCTION_SERVER_USER }}@${{ secrets.PRODUCTION_SERVER_HOST }}:~/docker-images/
- name: SSH into the server and run commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PRODUCTION_SERVER_HOST }}
username: ${{ secrets.PRODUCTION_SERVER_USER }}
password: ${{ secrets.PRODUCTION_SERVER_PASSWORD }}
port: 22
script: |
gunzip ~/docker-images/${{ env.IMAGE_NAME }}-latest.tar.gz
# Load the Docker image
docker load -i ~/docker-images/${{ env.IMAGE_NAME }}-latest.tar
# Stop the old container if it is running
docker stop ${{ env.CONTAINER_NAME }} || true
# Remove the old container
docker rm ${{ env.CONTAINER_NAME }} || true
# Run the new Docker container
docker run -d --name ${{ env.CONTAINER_NAME }} -p ${{ env.PORT }}:80 ${{ env.IMAGE_NAME }}:latest
# Remove the tarball
rm -f ~/docker-images/${{ env.IMAGE_NAME }}-latest.tar
- name: Cleanup
run: |
# Remove the local tarball after uploading
rm -f ${{ env.IMAGE_NAME }}-latest.tar.gz