github action部署到vps

2022年03月17日189 次阅读1 人喜欢
技术

在 ECS 上创建用户,并设置密码

  1. adduser github-action
  2. asswd passwd github-action

免密登陆

  1. 生成密钥
bash 复制代码
ssh-keygen -t rsa -C 'github-action' -f ~/.ssh/github_action
  1. 复制密钥到远程服务器
bash 复制代码
# ssh-copy-id
ssh-copy-id -i ~/.ssh/github_action.pub  [email protected]
  1. 设置默认登录
    因为同一台电脑可能既有 root 也有其他用户登录 ecs 所以可以配置指定 Host,指定 User,使用不同的密钥
yaml 复制代码
Host nnnnzs.cn
HostName github-action
User github-action
Port 22
PreferredAuthentications publickey
IdentityFile /Users/nnnnzs/.ssh/github_action
UseKeychain yes
AddKeysToAgent yes

赋予部署文件夹权限

bash 复制代码
sudo chmod -R 777 /dist

设置github-action的 secrets

https://github.com/NNNNzs/upload/settings/secrets/actions

编写自动部署脚本

mkdir -p .github/workflows
touch .github/workflows/build.yml

yml 复制代码
name: vue3 
on:
  push:
    branches: [master]
  pull_request:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: checkout code
        uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14'
      - name: install 
        run: npm install
      - name: build
        run: npm run build
      - name: deploy
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{secrets.KEY}}
          port: ${{ secrets.PORT }}
          source: "./dist/"
          target: ${{secrets.PATH}}
bash 复制代码
curl -H "Content-Type:application/json" -X POST -d '{"title":"自动部署","content":"upload部署完成","url":"https://api.nnnnzs.cn/upload"}' https://api.nnnnzs.cn/Api/msg

curl -H "Content-Type:application/json" -X POST -d '{"uid":"123"}' http://127.0.0.1:3000/rest/test

Docker 部署方案

当遇到网络问题无法推送到 Docker Hub 时,可以使用以下方案:构建完成后导出镜像为 tar 包,通过 scp 传输到服务器,然后加载镜像并部署。

Docker 部署流程

  1. 构建 Docker 镜像:在 GitHub Actions 中构建镜像(不推送到 Docker Hub)
  2. 导出镜像:使用 docker save 将镜像导出为 tar 包
  3. 传输镜像:使用 scp 将 tar 包传输到服务器
  4. 加载镜像:在服务器上使用 docker load 加载镜像
  5. 部署服务:执行部署脚本重新加载服务

GitHub Actions 工作流示例

yaml 复制代码
name: Docker Release

on:
  push:
    branches:
      - release
      - main

env:
  IMAGE_NAME: nnnnzs/react-nnnnzs-cn

jobs:
  build-and-deploy:
    name: 构建并部署 Docker 镜像
    runs-on: ubuntu-latest
    
    steps:
      - name: 检出代码
        uses: actions/checkout@v4

      - name: 设置版本号
        id: version
        run: |
          if git describe --tags --exact-match 2>/dev/null; then
            VERSION=$(git describe --tags --exact-match)
          else
            VERSION="v$(date +'%Y.%m.%d.%H')"
          fi
          echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT

      - name: 设置 Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 构建 Docker 镜像(不推送)
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.prod
          platforms: linux/amd64
          push: false
          tags: ${{ env.IMAGE_NAME }}:latest

      - name: 导出 Docker 镜像
        run: |
          IMAGE_TAG="${{ env.IMAGE_NAME }}:latest"
          IMAGE_FILE="react-nnnnzs-cn-${{ steps.version.outputs.VERSION }}.tar"
          docker save -o "${IMAGE_FILE}" "${IMAGE_TAG}"
          echo "IMAGE_FILE=${IMAGE_FILE}" >> $GITHUB_ENV

      - name: 配置 SSH 密钥
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          DEPLOY_PORT="${{ secrets.DEPLOY_PORT }}"
          DEPLOY_PORT=${DEPLOY_PORT:-22}
          ssh-keyscan -p ${DEPLOY_PORT} ${{ secrets.DEPLOY_HOST }} >> ~/.ssh/known_hosts

      - name: 传输镜像到服务器
        run: |
          DEPLOY_PORT="${{ secrets.DEPLOY_PORT }}"
          DEPLOY_PORT=${DEPLOY_PORT:-22}
          scp -i ~/.ssh/deploy_key \
              -P ${DEPLOY_PORT} \
              "${IMAGE_FILE}" \
              ${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_DIR }}/"${IMAGE_FILE}"

      - name: 在服务器上加载镜像并部署
        uses: appleboy/[email protected]
        with:
          host: ${{ secrets.DEPLOY_HOST }}
          username: ${{ secrets.DEPLOY_USER }}
          key: ${{ secrets.DEPLOY_SSH_KEY }}
          port: ${{ secrets.DEPLOY_PORT }}
          script: |
            cd ${{ secrets.DEPLOY_DIR }}
            IMAGE_FILE="react-nnnnzs-cn-${{ steps.version.outputs.VERSION }}.tar"
            IMAGE_TAG="nnnnzs/react-nnnnzs-cn:latest"
            
            # 加载镜像
            docker load -i "${IMAGE_FILE}"
            
            # 删除镜像文件
            rm -f "${IMAGE_FILE}"
            
            # 执行部署脚本
            bash "${{ secrets.DEPLOY_SCRIPT }}" deploy

服务器端部署脚本

服务器上的部署脚本(scripts/deploy.sh)需要支持从本地加载的镜像:

bash 复制代码
#!/bin/bash
# Docker 快速部署脚本

COMPOSE_FILE="docker-compose.prod.yml"
IMAGE_NAME="nnnnzs/react-nnnnzs-cn"
CONTAINER_NAME="react-nnnnzs-cn-prod"

# 拉取最新镜像(已弃用:现在使用 docker load 加载镜像)
pull_image() {
    echo "跳过镜像拉取(镜像已通过 docker load 加载)..."
}

# 停止旧容器
stop_old() {
    docker-compose -f $COMPOSE_FILE down || true
}

# 启动新容器
start_new() {
    docker-compose -f $COMPOSE_FILE up -d
}

# 部署流程
deploy() {
    check_docker
    check_env
    pull_image  # 跳过拉取
    stop_old
    start_new
    check_status
    cleanup
}

优势

  • 避免网络问题:不需要推送到 Docker Hub 或从 Docker Hub 拉取
  • 更快的部署:直接传输镜像文件,避免网络延迟
  • 更安全:镜像只在本地和服务器之间传输,不经过公共仓库
  • 版本控制:镜像文件名包含版本号,便于管理

注意事项

  1. 确保服务器有足够的磁盘空间存储镜像文件
  2. 镜像文件较大,传输时间取决于网络速度
  3. 部署完成后会自动删除镜像文件以节省空间
  4. 需要配置正确的 SSH 密钥和权限

常用actions

远程调试 tmate

https://github.com/marketplace/actions/debugging-with-tmate

加载评论中...