

为 Astro 博客添加多部署站点
为 Astro 博客添加多部署站点
前言#
最近还是在折腾博客,之前一直用的是 Vercel 部署,本身还是很优雅的,但是还是想要玩一些别的。具体来说,使用 Vercel 部署,我使用的就是 Vercel 的 Pages 功能,使用的自然是 Vercel 自己的服务器。同时,网络上几大其他的赛博菩萨,比如说 Cloudflare Pages 以及 GitHub Pages 等,都支持免费的 Pages 功能,多几个服务器来跑我的网页,而且不是同一个服务器,这样子可以避免单点故障。
Astro 本身其实支持了不同的 adapter,也可以很便捷的部署到不同的站点,所以就简单配置了一下,然后记录一下这个过程。
编辑配置文件#
首先,编辑 astro.config.mjs
文件,添加不同的 adapter 配置。
const platform = process.env.DEPLOYMENT_PLATFORM || 'vercel'
const isCloudflare = platform === 'cloudflare'
const isGithubPages = platform === 'github'
export default defineConfig({
site: isGithubPages ? 'https://axi404.github.io/' : (isCloudflare ? 'https://axi-blog.pages.dev/' : 'https://axi404.top/'),
trailingSlash: 'never',
adapter: isGithubPages ? undefined : (isCloudflare ? cloudflare() : vercel()),
output: isGithubPages ? 'static' : (isCloudflare ? 'static' : 'server'),
})
js整体的思路就是根据环境变量来判断当前的部署平台,然后根据不同的平台来选择不同的 adapter,然后默认的是使用 Vercel。在这里因为 Github 和 Cloudflare 都是在薅羊毛,没有进行氪金,所以说都是使用的静态站点,服务端渲染这种特性毕竟本来也不是必须得。
关于如何使用 Vercel 部署站点在 之前的文章 中已经介绍过了,这里就不再赘述了。主要介绍剩下的两种的过程。
Cloudflare Pages 的部署过程其实也有类似的博客,也就是我部署 R2 图床的博客 的那一篇,本身也就是直接绑定之后部署就好,之后每一次 Push 之后就会自动部署。
至于对于 Github Pages,其实就是需要写一个 Github Action 的文件,放到 .github/workflows/deploy.yml
中,然后每一次 Push 之后就会通过运行这个 Action 来部署。这一步其实直接交给 GPT 来做就好了,我的一个特殊的点在于我博客的仓库是一个 private 仓库,并且不是 axi404.github.io
的名称,因此需要在 Axi-Blog 的仓库中运行 Github Action,进行 build,并且将 build 的结果推送到 axi404.github.io
的仓库中。
简单介绍下这个方案,大概就是需要先创建一个 Token,打开 Github 的创建 Token 的 页面 ↗,然后在 Repository access 中选择 axi404.github.io
的仓库,仓库权限中给 Content 的 read and write,之后在 Axi-Blog
的仓库的 settings 中选择 Secrets and variables 中的 Actions 中添加一个 Secret,名字为 PERSONAL_TOKEN
,值为刚刚创建的 Token。
文件内容如下:
name: Deploy to Axi404.github.io
on:
push:
branches:
- main
permissions:
contents: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout source
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest
- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install dependencies
run: bun i
- name: Set environment variables
run: |
echo "DEPLOYMENT_PLATFORM=github" >> $GITHUB_ENV
- name: Build site
run: bun run build:github
- name: Deploy to Axi404.github.io
uses: peaceiris/actions-gh-pages@v3
with:
personal_token: ${{ secrets.PERSONAL_TOKEN }}
external_repository: Axi404/axi404.github.io
publish_branch: main
publish_dir: ./dist
force_orphan: true
yml即可。
服务器部署#
因为折腾了服务器,所以说也搞了个服务器部署,包括设置 Hook,以及设置反向代理。
首先基础配置 Git 跳过,之后安装 nginx 并且开放防火墙:
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
sudo ufw allow 80
sudo ufw allow 443
sudo ufw reload
bash然后 git clone
你的仓库,并且安装相关依赖。
之后是关键,首先配置反向代理:
server {
listen 80;
server_name blog.axi404.top;
root /var/www/blog;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
nginx在 Cloudflare 添加一个 A,内容是 blog,指向服务器 IP,关闭代理。
之后获得 https 证书:
sudo certbot --nginx -d blog.axi404.top --non-interactive --agree-tos -m [email protected]
bash之后配置 Hook,在服务器上创建一个文件 deploy.sh
,并且创建 log 文件夹,mkdir -p /var/log/blog
,脚本内容如下:
#!/bin/bash
LOG_DIR="/var/log/blog"
LOG_FILE="$LOG_DIR/deploy_$(date '+%Y-%m-%d_%H-%M-%S').log"
echo "$(date '+%Y-%m-%d %H:%M:%S') - deploy.sh started" | tee -a "$LOG_FILE"
cd /root/Axi-Blog || {
echo "Failed to cd to /root/Axi-Blog" | tee -a "$LOG_FILE"
exit 1
}
echo "git pull origin main ..." | tee -a "$LOG_FILE"
git pull origin main >> "$LOG_FILE" 2>&1
echo "Start build (try 1) ..." | tee -a "$LOG_FILE"
if ! bun run build >> "$LOG_FILE" 2>&1; then
echo "Build failed, retrying (try 2) ..." | tee -a "$LOG_FILE"
if ! bun run build >> "$LOG_FILE" 2>&1; then
echo "Build failed twice, aborting." | tee -a "$LOG_FILE"
exit 1
fi
fi
echo "Copying files ..." | tee -a "$LOG_FILE"
rm -rf /var/www/blog/* >> "$LOG_FILE" 2>&1
cp -r dist/* /var/www/blog/ >> "$LOG_FILE" 2>&1
chown -R www-data:www-data /var/www/blog >> "$LOG_FILE" 2>&1
echo "$(date '+%Y-%m-%d %H:%M:%S') - deploy.sh finished" | tee -a "$LOG_FILE"
bash之后写一个 hook,效果是每次 push 之后,只要 fetch,就执行部署。
首先创建:
mkdir ~/deploy-hook
cd ~/deploy-hook
npm init -y
npm install express
bash之后创建 Hook:
// hook.js
const express = require('express');
const { exec } = require('child_process');
const app = express();
app.post('/hook', (req, res) => {
res.send('Deploying...');
exec('bash /root/deploy.sh', (err, stdout, stderr) => {
if (err) {
console.error('❌ Error:', stderr);
} else {
console.log('✅ Output:\n', stdout);
}
});
});
app.listen(XXXX, () => {
console.log('🚀 Webhook listening on http://localhost:XXXX/hook');
});
js将上述 XXXX
替换为你的端口,然后运行 node hook.js &
即可。别忘了开放这个端口的防火墙。
接下来在 github 的 workflows 里面加一行,curl -X POST http://XXX.XXX.XXX.XXX:XXXX/hook
,即可。
结语#
内容反正大概就是这样,也不是很难,最后喜提两个新域名,一个是 axi-blog.pages.dev ↗,一个是 axi404.github.io ↗,前者是 Cloudflare Pages 的,后者是 Github Pages 的。
最后加了一个服务器,可以用 blog.axi404.top ↗ 访问。