本文主要记录我的博客从 Wordpress 到 Hexo 的过程。
国内访问(阿里云)
我选择了阿里云服务器作为我博客的国内访问主机。当然在国内服务器搭建网站需要备案。
具体方案在阿里云上搭建一个 Git 服务器,之后利用 Nginx 进行静态 HTML 文件的反向代理,以实现博客内容的展示。
Git服务器搭建
本文选择 Hexo 作为博客框架,Hexo 是一个基于 Node.js 的静态博客生成器,它能够将 Markdown 格式的文本转换成静态的 HTML 页面,而我在服务器上搭建 Git 仓库,主要是为了创建一个版本控制系统,用于管理我的 Hexo 博客代码和内容。
- 创建 git 用户
- 给 git 用户添加文件权限
找到User privilege specification部分,添加如下内容:
- 切换到 git 用户
- 安装 git
1 2
| sudo apt-get update sudo apt-get install git-core
|
- 创建仓库
1 2 3 4 5 6 7
| cd sudo mkdir repos sudo chown -R $USER:$USER /home/git/repos sudo chmod -R 755 /home/git/repos
cd repos git init --bare hexoBlog.git
|
配置 Nginx
- 安装 Nginx
1
| sudo apt-get install nginx -y
|
- 创建
repos\hexoBlog
目录,用于Nginx托管,修改目录所有权和权限
1 2 3 4
| cd /home/git/repos sudo mkdir hexBlog sudo chown -R $USER:$USER /home/git/repos/hexBlog sudo chmod -R 755 /home/git/repos/hexBlog
|
- 修改 nginx 配置
在 /etc/nginx/sites-available/
下添加需要代理的网站的配置文件。例如
1
| vim /etc/nginx/sites-available/infinite-zh.com
|
具体配置如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| server { listen 443 ssl; server_name infinite-zh.com www.infinite-zh.com;
ssl_certificate /etc/ssl/certs/infinite-zh.com.pem; ssl_certificate_key /etc/ssl/private/infinite-zh.com.key;
ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /home/git/repos/hexoBlog; index index.html index.htm index.nginx-debian.html;
location / { try_files $uri $uri/ =404; }
location = / { try_files /index.html =404; } }
server { listen 80; server_name infinite-zh.com www.infinite-zh.com; return 301 https://$host$request_uri; }
|
启用该配置文件
1
| sudo ln -s /etc/nginx/sites-available/infinite-zh.com /etc/nginx/sites-enabled/
|
- 重启Nginx服务,使得改动生效
1
| sudo service nginx restart
|
创建 Git 钩子
在之前创建的hexoBlog.git
裸仓库下有一个hooks
文件夹,在其中创建一个名为post-receive
的钩子文件:
命令如下:
1
| vim /home/repos/hexBlog.git/hooks/post-receive
|
在其中写入如下内容:
1 2 3
| #!/bin/bash
git --work-tree=/var/www/hexo --git-dir=/var/repo/hexo_static.git checkout -f
|
保存后退出
让该文件变为可执行文件
命令如下:
1
| chmod +x /home/repos/hexBlog.git/hooks/post-receive
|
配置 Https 访问
可以从阿里云的 数字证书管理服务(原SSL证书) 中获取免费证书,可以免费买20个,每一个可以用3个月,三个月得去换一下。
阿里云购买的服务器可以通过官网的云服务器部署进行自动部署,具体操作指南可以参考 部署SSL证书至阿里云轻量应用服务器或云服务器ECS。
![cas_deploy](https://images.infinite-zh.com/resource/hexo-blog-build/cas_deploy.png)
当然如果服务器不是阿里云是别的厂商的,则可以手动进行上传,具体文档参考 安装证书到服务器_数字证书管理服务。
OSS 配置
为了更好的访问博客的图片等资源,采用阿里云oss来进行存储。因为我需要将原来的一些图片批量上传,故设置了一个脚本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| package main
import ( "fmt" "log" "os" "path/filepath" "strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss" )
const ( endpoint = accessKeyID = accessKeySecret = bucketName = )
func uploadFile(client *oss.Client, bucketName, localFilePath, remoteFilePath string) error { bucket, err := client.Bucket(bucketName) if err != nil { return fmt.Errorf("获取bucket失败: %v", err) }
err = bucket.PutObjectFromFile(remoteFilePath, localFilePath) if err != nil { return fmt.Errorf("上传文件失败: %v", err) }
fmt.Printf("上传成功: %s -> %s\n", localFilePath, remoteFilePath) return nil }
func uploadDirectory(client *oss.Client, bucketName, localDir, remoteDir string) error { err := filepath.Walk(localDir, func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() && strings.HasPrefix(info.Name(), ".") { return filepath.SkipDir }
if !info.IsDir() && (strings.ToLower(info.Name()) == "readme.md") { return nil }
if !info.IsDir() { remotePath := filepath.Join(remoteDir, strings.TrimPrefix(path, localDir)) remotePath = strings.ReplaceAll(remotePath, "\\", "/") return uploadFile(client, bucketName, path, remotePath) } return nil }) return err }
func main() { client, err := oss.New(endpoint, accessKeyID, accessKeySecret) if err != nil { log.Fatalf("创建OSS客户端失败: %v", err) } fmt.Print("创建OSS客户端成功\n") localDir := "" remoteDir := ""
err = uploadDirectory(client, bucketName, localDir, remoteDir) if err != nil { log.Fatalf("上传文件夹失败: %v", err) } }
|
CDN 配置
CDN 主要是跟着阿里云官方指示配置域名等信息,可以选择之前备案的域名的子域名。
然后可以在 数字证书管理服务(原SSL证书) 配置 CDN 的Https 访问。
然后就可以通过子域名的方式访问 OSS 的资源,当首次访问资源的时候会发现,会发现 Response header 的X-Cache
为MISS TCP_MISS dirn:-2:-2
,表示没有命中缓存,需要直接从原始服务器获取数据
![cdn_test](https://images.infinite-zh.com/resource/hexo-blog-build/cdn_test.png)
国外访问(GitHub Page)
创建所需仓库
- 创建
hexo-source
仓库用来存放 Hexo 项目
- 创建
your.github.io
仓库用来存放静态博客页面
- 创建
blog-images
仓库用来存储博客图片等资源
将源代码文件和前段页面分开,还可以设置源代码仓库为private。
生成部署密钥
1
| ssh-keygen -f blog-deploy-key
|
当前目录下会有 blog-deploy-key
和 blog-deploy-key.pub
两个文件。
配置部署密钥
复制 blog-deploy-key
文件内容,在 blog
仓库 Settings -> Secrets and variables -> Actions -> New repository secret
页面上添加。
- 在
Name
输入框填写 DEPLOY_KEY
。
- 在
Value
输入框填写 blog-deploy-key
文件内容。
复制 blog-deploy-key.pub
文件内容,在 your.github.io
仓库 Settings -> Deploy keys -> Add deploy key
页面上添加。
- 在
Title
输入框填写 HEXO_DEPLOY_PUB
。
- 在
Key
输入框填写 blog-deploy-key.pub
文件内容。
- 勾选
Allow write access
选项。
此外还有 Github 的 ACCESS_TOKEN,位于头像 -> Settings -> Developer Settings -> Personal access tokens -> Tokens。
编写 Github Actions
在 blog
仓库根目录下创建 .github/workflows/deploy.yml
文件,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| name: DEPLOY
on: push: branches: - main
env: GIT_USER: xxxx GIT_EMAIL: xxxxx DEPLOY_REPO: xxxxxx/xxxxxxxx.github.io DEPLOY_BRANCH: gh-pages
jobs: build: name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }} runs-on: ubuntu-latest strategy: matrix: os: [ubuntu-latest] node_version: [20.x]
steps: - name: Checkout uses: actions/checkout@v4 with: token: ${{ secrets.ACCESS_TOKEN }} submodules: true
- name: Checkout deploy repo uses: actions/checkout@v4 with: repository: ${{ env.DEPLOY_REPO }} ref: ${{ env.DEPLOY_BRANCH }} path: .deploy_git
- name: Use Node.js ${{ matrix.node_version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node_version }}
- name: Configuration environment env: HEXO_DEPLOY_PRI: ${{secrets.DEPLOY_KEY}} run: | sudo timedatectl set-timezone "Asia/Shanghai" mkdir -p ~/.ssh/ echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan github.com >> ~/.ssh/known_hosts git config --global user.name $GIT_USER git config --global user.email $GIT_EMAIL - name: Install dependencies run: | npm ci - name: Deploy Hexo run: | npm run deploy
|
该 workflow 会在提交代码的时候,自动进行运行,效果如下。
![deploy](https://images.infinite-zh.com/resource/hexo-blog-build/deploy.png)
如果是第一次运行可能会出现,gh-pages 分支不存在的问题,可以手动添加一下分支来修复问题。
设置图片资源的 CDN
jsDelivr - A free, fast, and reliable CDN for JS and open source
使用 jsDelivr 作为 Github 仓库的 CDN,加速图片资源等的访问。
参考 qxdn 的方案,设置 Github Actions ,设置上传 tag 时自动发布release版本。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| name: release
permissions: contents: write
on: push: tags: - "v*.*.*"
jobs: build: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Release uses: softprops/action-gh-release@v1 with: draft: true
|
Reference
Hexo部署至服务器(Ubuntu 20.04) | 花猪のBlog (cnhuazhu.top)
在 GitHub Pages 上部署 Hexo | Hexo
利用 Github Actions 自动部署 Hexo 博客 | Sanonz