好久不见,今天分享一下我的网站是如何做智能DNS解析的案例。
现在看到这个网站被部署在一个 GitHub 仓库,我域名解析指向了 GitHub,因此可以通过域名直接访问这个网站。
但是目前在中国大陆访问比较慢,于是我采购了一台中国大陆的服务器。目标:
- 在大陆的 IP 地址访问,解析到大陆服务器。
- 在境外访问,解析到 GitHub。
项目原本的增量更新逻辑不变:即通过 GitHub Actions
,每次变更自动更新不一致的文件。
实现这个需求的关键在于使用智能DNS解析,也就是根据访问者的地理位置将域名解析到不同的 IP 地址。
域名解析修改
在阿里云服务选择云解析 DNS
。相关配置如下:
主机记录 | 记录类型 | 解析线路 | 记录值 |
---|---|---|---|
www | CNAME | 境外 | 你的Github用户ID.github.io |
@ | CNAME | 境外 | 你的Github用户ID.github.io |
www | A | 中国地区 | 我的服务器IP |
@ | A | 中国地区 | 我的服务器IP |
服务器配置
在服务器上,需要部署一个Web服务器(如 Nginx 或 Apache),并配置它来服务项目静态文件。大部分服务器都是开箱即有。我使用的是宝塔面板,添加PHP项目
,简单的配置了一下域名和SSL
证书。找到项目指向的文件夹/www/wwwroot/jiangmiemie.com
,后续将 GitHub 生成的静态资源传输到这里即可。
如何将项目文件同步到这台服务器上。这里计划使用rsync
增量同步,使用ssh
链接。
rsync
rsync
比 scp
更适合同步大量文件,因为它可以只传输有变化的部分。
我的这台服务器是阿里云系统(不是 Ubuntu),需要使用命令:yum install -y rsync
进行安装。
ssh
需要在防火墙中打开的端口:22
、80
、443
虽然我们可以直接通过账号密码 登录 ssh,但是账号密码权限太高,因此设置一个仅用于部署的 ssh 密钥。
# 生成密钥对(在服务器上)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/github_deploy_key -N ""
# 查看生成的文件
ls -la ~/.ssh/
# 会看到:
# github_deploy_key (私钥)
# github_deploy_key.pub (公钥)
# 将公钥添加到authorized_keys
cat ~/.ssh/github_deploy_key.pub >> ~/.ssh/authorized_keys
# 设置正确权限(过低没有权限,过高ssh会认为文件不安全)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 600 ~/.ssh/github_deploy_key
# 测试密钥是否工作(在服务器上)应该能直接连接,不需要密码
ssh -i ~/.ssh/github_deploy_key root@localhost
# 显示私钥内容(复制到GitHub Secrets)
cat ~/.ssh/github_deploy_key
GitHub Workflow 修改
完整配置如下,主要变更内容为Setup SSH
和Deploy to server
。
因为GitHub Actions
是所有人都能看到的,因此为了安全,你需要把服务器 IP 地址、连接信息等配置为密钥变量。下面代码中${{ secrets.SSH_PRIVATE_KEY }}
这样格式的都是密钥变量。
把你的 IP 地址和刚刚终端显示的私钥
复制到 GitHub Secrets。
在你的 GitHub 仓库页面,进入 Settings
-> Secrets and variables
-> Actions
。
点击 New repository secret
。
Name 填写一个有意义的名称,比如我设置的是SSH_PRIVATE_KEY
和IP
。
-
IP
的 Secret 框中,仅粘贴你的 IP 地址。例如:192.168.10.11
-
SSH_PRIVATE_KEY
的 Secret 框中,粘贴从-----BEGIN OPENSSH PRIVATE KEY-----
到-----END OPENSSH PRIVATE KEY-----
完整内容。
name: Build HTML
on: push
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- run: |
npm install
npm run build
- uses: peaceiris/actions-gh-pages@v3
if: github.ref == 'refs/heads/main'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
- name: Setup SSH
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Deploy to server
run: |
mkdir -p ~/.ssh
ssh-keyscan -H ${{ secrets.IP }} >> ~/.ssh/known_hosts
rsync -avz --exclude='.user.ini' ./build/ root@${{ secrets.IP }}:/www/wwwroot/jiangmiemie.com
env:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SERVER_IP: ${{ secrets.IP }}
ssh-keyscan -H ${{ secrets.IP }} >> ~/.ssh/known_hosts
表示将服务器的公钥添加到 known_hosts 文件中。
rsync -avz --exclude='.user.ini' ./build/ root@${{ secrets.IP }}:/www/wwwroot/jiangmiemie.com
表示将./build/
文件夹同步到/www/wwwroot/jiangmiemie.com
文件夹。
参数 | 作用 | 详细说明 |
---|---|---|
rsync | 远程同步工具 | 比 scp 更智能,只传输变化的部分 |
-a | 归档模式 | 保留文件权限、时间戳、符号链接等所有属性 |
-v | 详细输出 | 显示传输过程的详细信息 |
-z | 压缩传输 | 传输时压缩数据,减少网络带宽 |
--exclude='.user.ini' | 排除文件 | 跳过服务器自动生成的系统文件 |
./build/ | 源目录 | 本地构建好的静态文件目录 |
root@IP:/path/ | 目标地址 | 服务器上的部署目录 |
每次你推送代码到 GitHub,工作流会自动构建并将变化同步到服务器,一次修改,处处生效!