自动部署
2022年4月19日
本文介绍如何利用 Git 和 GitHub Action,自动部署代码到服务器。
提示
由于 Centos 仍然是用 GitV1,本教程使用 Ubuntu 20.04 进行教学。
服务器
为了能供自动部署到服务器,我们需要让服务器的网站目录成为一个 Git 仓库,这样我们可以在 GitHub Actions 中,通过向服务器对应 GitHub 仓库推送网站内容,使服务器网站获得自动更新。下面是服务器侧的部署配置
添加账户
为了安全,首先需要使用命令创建 Git 用户,为了安全请务必设置密码。
sudo adduser git
之后,查看部署目录所在组,git 用户添加到组中。
usermod -a -G <目录所在组> git
然后将部署目录的权限设置为 775
,即允许同组访问。这样 git 就有权限访问部署目录。
添加权限
创建 ~/.ssh/
文件夹,生成 authorized_keys
文件,并设置其权限为 600
。
mkdir -p ~/.ssh/
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
之后将需要赋予权限的用户公钥依次粘贴至该文件,这样相关用户即可以使用对应私钥,向服务器相关仓库推送代码。
创建仓库
回到 /home/git/
,创建所需的文件夹:
cd ~
mkdir <仓库名>
进入文件夹,使用
git init --separate-git-dir=. <部署位置>
这会将 git 库保持在 /home/git/<仓库名>
下,同时将工作区设置到部署文件夹中。
接下来执行:
git config receive.denyCurrentBranch ignore
这是由于 Git 默认拒绝外部对当前分支的推送操作,因为这可能会覆盖或变更工作区文件。
设置完毕后,Git 会允许外部对当前工作区分支进行推送操作。
GitHub Actions
在 GitHub 一侧,我们需要通过 GitHub Action,在新代码推送时自动构建网站,并部署到 GitHub 的 gh-pages 分支。之后,GitHub Action 将该分支的变动推送服务器的对应仓库,完成网站的自动部署。
之后只需要使用 GitHub Action 通过 Git 推送到 git@<domain>:<部署目录> gh-pages
即可。
# 自动部署的名称
name: GitHub pages deploy
# 自动部署的条件
on:
push:
branches:
- master
jobs:
# 构建网站并部署到 GitHub Pages
deploy-gh-pages:
# 运行环境
runs-on: ubuntu-latest
# 步骤
steps:
# 第一步: 下载源码
- name: Checkout
# action 配置详见 https://github.com/actions/checkout
uses: actions/checkout@v3
with:
# 如果本项目包含了子模块 (git submodules),需要将此项设置为 true
# submodules: true
# 这是获取历史 commit 的深度,默认为 1,即只拉取最后一个 commit
# 这样可以加快拉取速度
#
# 如果项目使用 VuePress,为了正确通过 Git 历史提交记录生成页面的最后更新时间
# 需要设置为 0 以拉取完整的 git 历史提交
# fetch-depth: 0
# 如果子模块包含私有仓库,需要设置 ssh key 或 token 以保证拥有拉取相应仓库的权限
# 您可以将 ssh-key 设置为 github 绑定公钥对应的私钥
# 也可以新建一个具有相关仓库访问权限的 github token
# token:
# 缓存 node_modules 以避免重复安装
- uses: actions/cache@v3
id: node-modules
with:
# 需要缓存的路径
path: node_modules/
# 缓存的 key
key: ${{ runner.os }}-node-modules-${{ hashFiles('yarn.lock') }}
# 恢复 key
restore-keys: |
${{ runner.os }}-node-modules-
# 安装依赖
- name: Install Deps
# 只有没有命中缓存才会执行
if: steps.node-modules.outputs.cache-hit != 'true'
# 严格按照 yarn.lock 安装依赖
run: yarn install --frozen-lockfile
# 构建项目
- name: Build
# 项目的构建命令
run: yarn run build
# 第四步,部署
- name: Deploy
# action 配置详见 https://github.com/JamesIves/github-pages-deploy-action
uses: JamesIves/github-pages-deploy-action@v4
with:
# 部署到的分支
branch: gh-pages
# 需要部署的文件夹
folder: dist
# 部署到服务器
deploy-server:
runs-on: ubuntu-latest
# 确保在部署到 GitHub Pages 之后执行
needs: deploy-gh-pages
steps:
# 检出网站代码
- name: Checkout
uses: actions/checkout@v3
with:
# 检出 gh-pages 分支
ref: gh-pages
# 获取全部的历史提交
fetch-depth: 0
# 配置环境
- name: Configuration environment
# 写入私钥、配置 Git 用户名,写入服务器地址
# 您需要自行将服务器的私钥写入 secrets 的 SSH_PRIVATE_KEY
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan <your domain> >> ~/.ssh/known_hosts
git config --global user.name 'Your Name'
git config --global user.email 'You email'
# 部署到服务器
- name: Deploy
# 使用 Git 将网站代码强制推送到远程的网站目录
# 并使用 SSH 连接服务器进入网站目录手动切换到最新提交
run: |
git push -f git@<your domain>:<deploy dir> gh-pages
ssh git@<your domain> "cd <deploy dir> && git reset --hard HEAD"