Skip to content

Commit 7a8ebe7

Browse files
EmptyDustcodex
andcommitted
feat(site): migrate deployment workflow to rainyun
Co-authored-by: Codex <codex@openai.com>
1 parent aacf06f commit 7a8ebe7

4 files changed

Lines changed: 216 additions & 17 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ jobs:
1515
runs-on: ubuntu-latest
1616
env:
1717
TZ: Asia/Shanghai
18-
permissions:
19-
contents: write
2018
concurrency:
2119
group: ${{ github.workflow }}-${{ github.ref_name }}
2220

@@ -46,21 +44,83 @@ jobs:
4644

4745
- name: 安装项目依赖
4846
run: |
49-
# 这一步会根据新的 package.json 安装所有东西
50-
# 包括:hexo核心、渲染器(pug/stylus)、gulp、bangumi插件
5147
yarn install --immutable
5248
49+
- name: 校验 Rainyun 部署参数
50+
env:
51+
RAINYUN_HOST: ${{ secrets.RAINYUN_HOST }}
52+
RAINYUN_PORT: ${{ secrets.RAINYUN_PORT }}
53+
RAINYUN_USER: ${{ secrets.RAINYUN_USER }}
54+
RAINYUN_TARGET_DIR: ${{ secrets.RAINYUN_TARGET_DIR }}
55+
RAINYUN_SSH_KEY: ${{ secrets.RAINYUN_SSH_KEY }}
56+
run: |
57+
for key in RAINYUN_HOST RAINYUN_USER RAINYUN_TARGET_DIR RAINYUN_SSH_KEY; do
58+
if [ -z "${!key}" ]; then
59+
echo "::error::缺少 GitHub Secret: ${key}"
60+
exit 1
61+
fi
62+
done
63+
64+
if [ -z "${RAINYUN_PORT}" ]; then
65+
echo "RAINYUN_PORT 未配置,使用默认端口 22"
66+
fi
67+
68+
- name: 覆盖站点 URL
69+
env:
70+
SITE_URL: ${{ secrets.SITE_URL }}
71+
SITE_ROOT: ${{ secrets.SITE_ROOT }}
72+
run: |
73+
if [ -z "${SITE_URL}" ] && [ -z "${SITE_ROOT}" ]; then
74+
exit 0
75+
fi
76+
77+
node <<'EOF'
78+
const fs = require('fs');
79+
const path = '_config.yml';
80+
let text = fs.readFileSync(path, 'utf8');
81+
82+
if (process.env.SITE_URL) {
83+
text = text.replace(/^url:\s*.*/m, `url: ${process.env.SITE_URL}`);
84+
}
85+
86+
if (process.env.SITE_ROOT) {
87+
text = text.replace(/^root:\s*.*/m, `root: ${process.env.SITE_ROOT}`);
88+
}
89+
90+
fs.writeFileSync(path, text);
91+
EOF
92+
5393
- name: 生成静态文件
5494
run: |
5595
npx hexo clean
5696
npx hexo bangumi -u
5797
npx hexo generate
58-
# 如果以后需要 gulp,取消注释即可,不需要再安装 gulp-cli
59-
# npx gulp
6098
61-
- name: Deploy
62-
uses: peaceiris/actions-gh-pages@v4
99+
- name: 加载 SSH 私钥
100+
uses: webfactory/ssh-agent@v0.9.1
63101
with:
64-
github_token: ${{ secrets.GITHUB_TOKEN }}
65-
publish_dir: ./public
66-
publish_branch: gh-pages
102+
ssh-private-key: ${{ secrets.RAINYUN_SSH_KEY }}
103+
104+
- name: 写入 known_hosts
105+
env:
106+
RAINYUN_HOST: ${{ secrets.RAINYUN_HOST }}
107+
RAINYUN_PORT: ${{ secrets.RAINYUN_PORT }}
108+
run: |
109+
mkdir -p ~/.ssh
110+
chmod 700 ~/.ssh
111+
ssh-keyscan -p "${RAINYUN_PORT:-22}" -H "${RAINYUN_HOST}" >> ~/.ssh/known_hosts
112+
113+
- name: 部署到 Rainyun
114+
env:
115+
RAINYUN_HOST: ${{ secrets.RAINYUN_HOST }}
116+
RAINYUN_PORT: ${{ secrets.RAINYUN_PORT }}
117+
RAINYUN_USER: ${{ secrets.RAINYUN_USER }}
118+
RAINYUN_TARGET_DIR: ${{ secrets.RAINYUN_TARGET_DIR }}
119+
RAINYUN_POST_DEPLOY: ${{ secrets.RAINYUN_POST_DEPLOY }}
120+
run: |
121+
ssh -p "${RAINYUN_PORT:-22}" "${RAINYUN_USER}@${RAINYUN_HOST}" "mkdir -p '${RAINYUN_TARGET_DIR}'"
122+
rsync -az --delete -e "ssh -p ${RAINYUN_PORT:-22}" ./public/ "${RAINYUN_USER}@${RAINYUN_HOST}:${RAINYUN_TARGET_DIR}/"
123+
124+
if [ -n "${RAINYUN_POST_DEPLOY}" ]; then
125+
ssh -p "${RAINYUN_PORT:-22}" "${RAINYUN_USER}@${RAINYUN_HOST}" "${RAINYUN_POST_DEPLOY}"
126+
fi

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Fengling's free website.
55

66
- `master`: site code, Hexo config, themes, and deployment workflow
77
- `content`: authored Markdown and content data only
8-
- `gh-pages`: generated static files published by GitHub Actions
8+
- GitHub Actions: builds from `master + content` and syncs the generated `public/` directory to Rainyun over SSH
99

1010
Content paths are defined in `tools/content-paths.txt`.
1111

@@ -32,4 +32,19 @@ GitHub Actions now builds the site from:
3232
- the latest `master` branch for code and build configuration
3333
- the latest `content` branch for posts and page content
3434

35-
The deploy workflow runs on pushes to `master` or `content`, imports `origin/content` into the checked-out `master` tree, builds the site, and publishes to `gh-pages`.
35+
The deploy workflow runs on pushes to `master` or `content`, imports `origin/content` into the checked-out `master` tree, builds the site, and syncs `public/` to Rainyun with `rsync`.
36+
37+
## Rainyun Setup
38+
39+
Configure these GitHub Secrets before enabling deployment:
40+
41+
- `RAINYUN_HOST`: Rainyun server IP or domain
42+
- `RAINYUN_PORT`: SSH port, usually `22`
43+
- `RAINYUN_USER`: deploy user, for example `root`
44+
- `RAINYUN_TARGET_DIR`: static site root on the server, for example `/var/www/emptydust`
45+
- `RAINYUN_SSH_KEY`: private key used by GitHub Actions to log into the server
46+
- `RAINYUN_POST_DEPLOY`: optional remote command after upload, for example `sudo systemctl reload nginx`
47+
- `SITE_URL`: optional production site URL used during Hexo build
48+
- `SITE_ROOT`: optional Hexo root, default `/`
49+
50+
See [docs/rainyun-deploy.md](docs/rainyun-deploy.md) for the server-side checklist and an example Nginx config.

_config.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,8 @@ ignore:
111111
theme: anzhiyu
112112

113113
# Deployment
114-
## Docs: https://hexo.io/docs/one-command-deployment
114+
## Production deployment is handled by GitHub Actions and synced to Rainyun via SSH/rsync.
115115
deploy:
116-
type: git
117-
repo: git@github.com:EmptyDust/EmptyDust.github.io.git
118-
branch: gh-pages
119116

120117
pandoc:
121118
args:

docs/rainyun-deploy.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Rainyun 部署说明
2+
3+
这个仓库已经改成:
4+
5+
- `master` 保存站点代码、主题配置、GitHub Actions 工作流
6+
- `content` 保存文章和页面内容
7+
- GitHub Actions 在 `master``content` 更新后自动构建,并把 `public/` 同步到 Rainyun
8+
9+
## 1. 准备 Rainyun 服务器
10+
11+
推荐使用一台 Linux 云服务器,并保证:
12+
13+
- 可以通过 SSH 登录
14+
- 已安装 `nginx`
15+
- 已安装 `rsync`
16+
- 站点目录已经创建,例如 `/var/www/emptydust`
17+
18+
Rainyun 官方文档:
19+
20+
- 连接服务器: https://www.rainyun.com/docs/rgs/detail/connect/
21+
- 管理实例与绑定域名入口: https://www.rainyun.com/docs/rgs/detail/manage/
22+
- 如果你想用面板,也可以直接预装 1Panel: https://www.rainyun.com/docs/guide/cloud/1panel/
23+
24+
## 2. 服务器初始化
25+
26+
以 Ubuntu/Debian 为例:
27+
28+
```bash
29+
sudo apt update
30+
sudo apt install -y nginx rsync
31+
sudo mkdir -p /var/www/emptydust
32+
sudo chown -R $USER:$USER /var/www/emptydust
33+
```
34+
35+
## 3. Nginx 配置示例
36+
37+
把下面内容保存为 `/etc/nginx/sites-available/emptydust.conf`
38+
39+
```nginx
40+
server {
41+
listen 80;
42+
server_name example.com www.example.com;
43+
44+
root /var/www/emptydust;
45+
index index.html;
46+
47+
location / {
48+
try_files $uri $uri/ =404;
49+
}
50+
51+
location = /search.json {
52+
add_header Cache-Control "no-cache";
53+
}
54+
}
55+
```
56+
57+
启用配置:
58+
59+
```bash
60+
sudo ln -sf /etc/nginx/sites-available/emptydust.conf /etc/nginx/sites-enabled/emptydust.conf
61+
sudo nginx -t
62+
sudo systemctl reload nginx
63+
```
64+
65+
如果已经绑定域名并准备上 HTTPS,再额外配置证书即可。
66+
67+
## 4. GitHub Secrets
68+
69+
在 GitHub 仓库里配置以下 Secrets:
70+
71+
- `RAINYUN_HOST`
72+
- `RAINYUN_PORT`
73+
- `RAINYUN_USER`
74+
- `RAINYUN_TARGET_DIR`
75+
- `RAINYUN_SSH_KEY`
76+
- `RAINYUN_POST_DEPLOY` 可选
77+
- `SITE_URL` 可选
78+
- `SITE_ROOT` 可选
79+
80+
推荐值示例:
81+
82+
```text
83+
RAINYUN_HOST=1.2.3.4
84+
RAINYUN_PORT=22
85+
RAINYUN_USER=root
86+
RAINYUN_TARGET_DIR=/var/www/emptydust
87+
RAINYUN_POST_DEPLOY=sudo systemctl reload nginx
88+
SITE_URL=https://example.com/
89+
SITE_ROOT=/
90+
```
91+
92+
`RAINYUN_SSH_KEY` 使用 GitHub Actions 专用私钥,对应公钥要加入服务器:
93+
94+
```bash
95+
mkdir -p ~/.ssh
96+
chmod 700 ~/.ssh
97+
cat >> ~/.ssh/authorized_keys
98+
chmod 600 ~/.ssh/authorized_keys
99+
```
100+
101+
把公钥粘进去保存即可。
102+
103+
## 5. 触发部署
104+
105+
部署会在这些情况下自动执行:
106+
107+
- push 到 `master`
108+
- push 到 `content`
109+
- 手动触发 `workflow_dispatch`
110+
111+
工作流会执行:
112+
113+
1. checkout `master`
114+
2. 拉取并导入 `content`
115+
3. 安装主题与依赖
116+
4. `hexo clean && hexo bangumi -u && hexo generate`
117+
5. `rsync --delete` 上传 `public/` 到 Rainyun
118+
119+
## 6. 本地核对点
120+
121+
如果线上访问异常,优先检查:
122+
123+
- `SITE_URL` 是否和最终域名一致
124+
- `RAINYUN_TARGET_DIR` 是否就是 Nginx 的 `root`
125+
- SSH 端口和用户是否正确
126+
- 服务器是否安装了 `rsync`
127+
- Nginx 是否已 reload

0 commit comments

Comments
 (0)