github action部署到vps
2022年03月17日189 次阅读1 人喜欢
技术
在 ECS 上创建用户,并设置密码
adduser github-actionasswd passwd github-action
免密登陆
- 生成密钥
bash
ssh-keygen -t rsa -C 'github-action' -f ~/.ssh/github_action
- 复制密钥到远程服务器
bash
# ssh-copy-id
ssh-copy-id -i ~/.ssh/github_action.pub [email protected]
- 设置默认登录
因为同一台电脑可能既有 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 部署流程
- 构建 Docker 镜像:在 GitHub Actions 中构建镜像(不推送到 Docker Hub)
- 导出镜像:使用
docker save将镜像导出为 tar 包 - 传输镜像:使用
scp将 tar 包传输到服务器 - 加载镜像:在服务器上使用
docker load加载镜像 - 部署服务:执行部署脚本重新加载服务
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 拉取
- 更快的部署:直接传输镜像文件,避免网络延迟
- 更安全:镜像只在本地和服务器之间传输,不经过公共仓库
- 版本控制:镜像文件名包含版本号,便于管理
注意事项
- 确保服务器有足够的磁盘空间存储镜像文件
- 镜像文件较大,传输时间取决于网络速度
- 部署完成后会自动删除镜像文件以节省空间
- 需要配置正确的 SSH 密钥和权限