1. 程式人生 > 實用技巧 >使用 rsync-deploy-action 同步 Hexo 部落格到個人伺服器

使用 rsync-deploy-action 同步 Hexo 部落格到個人伺服器

前幾天寫了個基於 rsync 進行檔案同步的 Action -> rsync-deploy-action。目的有三個:

  • 1、深入瞭解波 GitHub Actions,感受下 GitHub 的文件;
  • 2、個人部落格在我的騰訊雲 CVM 伺服器上是部署有一份的「域名:shan333.cn」,之前的部落格同步方式是通過 Linux 的定時任務,覺得不太行,當前部落格的更新並沒有那麼頻繁,沒必要每隔幾個小時就 git pull 一下,且伺服器還掛著其他東西,效能還是有點損耗的,換成通過 rsync 進行主動推送的方式好點;
  • 3、熟悉波 SSH 協議和 rsync 協議。

今天擼一篇文章簡單記錄下這次折騰。

rsync-deploy-action 的建立

挑 rsync 協議,不挑 FTP 或 scp 的新建 GitHub Actions 的部分原因是 rsync 可以做增量備份。GitHub Action 有三種類別,即 Docker container、JavaScript 和 Composite run steps。這次手擼的 Action 歸屬於 GitHub 官方文件介紹的 Docker container action。rsync-deploy-action 已經發布到 GitHub 的 Marketplace。源倉庫地址:https://github.com/yeshan333/rsync-deploy-action

rsync 與其他檔案傳輸工具(如 FTP 或 scp)不同,rsync 的最大特點是會檢查傳送方和接收方已有的檔案,僅傳輸有變動的部分(預設規則是檔案大小或修改時間有變動)。

rsync-deploy-action 基於 SSH 協議進行檔案的遠端同步,從元資料檔案 action.yml 可以看到,Action 支援 8 個引數「6個必選,2個可選」。

name: 'rsync-deploy-action'
description: 'Synchronize files to the remote server using the SSH private key'
inputs:
  ssh_login_username:
    description: 'SSH login username'
    required: true
  remote_server_ip:
    description: 'remote server ip'
    required: true
  ssh_port:
    description: 'remote server SSH port'
    required: true
    default: "22"
  ssh_private_key:
    description: 'login user SSH private key'
    required: true
  source_path:
    description: 'The source storage path of the synchronous files'
    required: true
  destination_path:
    description: 'The destination storage path of the synchronous files'
    required: true
  ssh_args:
    description: 'SSH args'
    required: false
  rsync_args:
    description: 'rsync args'
    required: false

outputs:
  start_time:
    description: 'Start time of synchronization'
  end_time: # id of output
    description: 'End time of synchronization'
runs:
  using: 'docker'
  image: 'Dockerfile'
  args:
    - ${{ inputs.ssh_login_username }}
    - ${{ inputs.remote_server_ip }}
    - ${{ inputs.ssh_port }}
    - ${{ inputs.ssh_private_key }}
    - ${{ inputs.source_path }}
    - ${{ inputs.destination_path }}
    - ${{ inputs.ssh_args }}
    - ${{ inputs.rsync_args }}

branding:
  icon: 'file'
  color: 'green'

利用 rsync-deploy-action 的 Dockerfile 檔案配合 Action 執行日誌可以一窺 GitHub Actions 背後是如何執行的。 Action 的 with 引數的傳遞在一定程度上利用了 Dockerfile 的 ENTRYPOINT。

# Container image that runs your code
FROM alpine:latest

RUN apk update \
 && apk upgrade \
 && apk add --no-cache \
            rsync \
            openssh-client

# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh

# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]

接下來介紹下利用 rsync-deploy-action 進行 Hexo 部落格同步到個人騰訊雲 CVM 伺服器的過程。

Hexo 部落格同步到雲伺服器

由於 rsync 是基於 SSH 協議的,rsync-deploy-action 需要使用到 SSH 私鑰,所以需要先建立一個可以進行 SSH 遠端登入的使用者,不建議直接使用 root 使用者。

SSH 金鑰登入

1、先配置好遠端騰訊雲 CVM 伺服器 SSH 允許金鑰登入。編輯 SSH 配置檔案 /etc/ssh/sshd_config。

vim /etc/ssh/sshd_config
  • StrictModes yes 改成 StrictModes no (去掉註釋後改成 no)
  • 找到 #PubkeyAuthentication yes 改成 PubkeyAuthentication yes (去掉註釋)
  • 找到 #AuthorizedKeysFile .ssh/authorized_keys 改成 AuthorizedKeysFile .ssh/authorized_keys (去掉註釋)

儲存後,重啟 sshd。

systemctl restart sshd

2、新建使用者 github,用於遠端 SSH 免密登入。

在遠端伺服器執行如下命令:

# root 使用者下建立使用者 github 並且指定 HOME 目錄
useradd -d /home/github github
# 也可以使用 adduser github,adduser會自動建立 HOME 目錄等
# 設定 github 使用者密碼,用於後續 SSH 登入公鑰的上傳
passwd github

3、在本地 PC 執行如下命令,建立用於登入的金鑰對。

# 生成金鑰對
ssh-keygen -t rsa -b 4096 -C "[email protected]"
# 將生成的公鑰上傳到雲伺服器,server_ip 為伺服器 IP 地址,ssh_port 為 SSH 埠號
cat ~/.ssh/id_rsa.pub | ssh github@server_ip -p ssh_port "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# ssh 金鑰登入測試,server_ip 為伺服器 IP 地址,ssh_port 為 SSH 埠號
ssh -p ssh_port -i ~/.ssh/id_rsa github@server_ip

以上操作完成沒問題之後,即可使用 rsync-deploy-action 了,後面以個人 Hexo 部落格的同步為例子,簡單看下如何使用此 Action。

Hexo 部落格同步

個人 Hexo 部落格之前已經配置過 GitHub Action 的 workflows 進行部落格的自動部署「部落格源倉庫:yeshan333/actions-for-hexo-blog」,所以再添加個 step 給 rsync-deploy-action 即可啟用部落格同步。step 宣告如下:

name: Site CI

on:
  pull_request:
    branches: [master]
  push:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      ......
      - name: Release to GitHub Pages
        run: |
          git config --global user.email "[email protected]"
          git config --global user.name "yeshan333"
          git clone [email protected]:yeshan333/yeshan333.github.io.git .deploy_git
          chmod 755 -R .deploy_git
          hexo clean
          hexo generate
          hexo deploy
      - name: Push to tencentyun CVM
        uses: yeshan333/[email protected]
        with:
          ssh_login_username: ${{ secrets.SSH_LOGIN_USERNAME }}
          remote_server_ip: ${{ secrets.REMOTE_SERVER_IP }}
          ssh_port: ${{ secrets.SSH_PORT }}
          ssh_private_key: ${{ secrets.SSH_PRIVATE_KEY }}
          source_path: ./.deploy_git/*
          destination_path: ~/shan333.cn
          rsync_args: --exclude="./.deploy_git/.git/*"

workflow 中名為 Push to tencentyun CVM 的 step 會將 .deploy_git 下的所有檔案上傳到雲伺服器「存放到 ~/shan333.cn 目錄下」,熟悉 Hexo 的朋友應該知道 hexo deploy 生成的檔案會放在 .deploy_git 目錄下,這裡用到了 Hexo 的一個 Plugin -> hexo-deployer-git。其實也可以將 hexo generate 生成的 public 目錄下的所有檔案同步到雲伺服器。

rsync-deploy-action 使用到的引數解釋「有部分資料也算是隱私資料,這裡意思下用了 GitHub 的 repository secrets」:

  • ssh_login_username:可以進行 SSH 金鑰登入的使用者名稱,即之前配置好的 github 使用者。
  • remote_server_ip:雲伺服器 IP
  • ssh_private_key:SSH 登入使用者的私鑰,即之前的 ~/.ssh/id_rsa 檔案的內容
  • source_path:部落格相關所有檔案路徑
  • destination_path:同步到雲伺服器的目標路徑~/shan333.cn,即/home/github/shan333.cn
  • rsync_args:action 的可選引數,.git 目錄是沒必要同步上傳的,排除掉

“大功告成”。rsync 協議的更多介紹可參考:WangDoc.com rsync

More

個人的騰訊雲 CVM 伺服器之前為了方便維護安裝了個運維面板BT.CN,Hexo 部落格是用過 Nginx Serving 的,但 Nginx 是通過運維面板安裝的,預設的 user 為 www「寶塔對 Nginx 的配置檔案進行了拆分」,但同步後的部落格是放在 github 使用者的 HOME 目錄下的 shan333.cn 目錄中的,www 無許可權執行部落格的相關檔案(403 Forbidden),所以需要操作波給 www 使用者可執行許可權,讓 Nginx Worker 可以 serving 部落格:

# root 使用者下執行,github 目錄下的所有檔案 755 許可權
chmod -R 755 /home/github
# 將 www 使用者新增到 github user group
usermod www -G -a www

參考

本文由部落格群發一文多發等運營工具平臺 OpenWrite 釋出