此文记录本站的搭建流程,主要环境是 Windows 10 桌面系统和 Ubuntu 18.04 云服务器。逻辑是将本地桌面端每一次的更新推送到 GitHub 再同步到云服务器。大概思路如下
- 在 Windows 上通过 Hugo 架设网站,进行 Markdown 写作。
- 通过 Git 将更新推送到 GitHub 仓库。
- 配置工作流,一旦源站发生变动,Git Action 就会在虚拟环境中生成网站,并将其同步到绑定了域名的云服务器上。
备案的网站是需要存放在境内的服务器上,若不想备案,或是网站位于境外,则可以忽略最后一步,选择将网站托管到 Vercel。这样不仅省去了麻烦,而且国内的访问速度也不差1。本流程主要参考烂磁头的教程,其中详细介绍了工作流的具体作用。本文在此基础上增加了自动部署 Hugo 和 pandoc 的工作流,以简化本地操作2,同时也画蛇添足地增加了详尽的说明,既方便新手,也作为备忘录。整个过程虽然繁琐,配置好之后,就只需专注于写作。
Hugo
Hugo 是一个静态网站生成器,优点是网站生成速度非常快(以毫秒计),源站可移植性好,以及拥有多种主题,拿来即用;缺点是自定义主题需要熟悉 Hugo 语法,但自己动手岂不有趣。具体设置如下:
下载功能最全的 extended 压缩包,解压。这是可移植软件,无需安装,直接将文件夹移动到常用的软件安装文件夹中即可。
设置环境变量,以便在终端直接运行软件。在搜索栏中查找“编辑系统环境变量”,点击弹出窗口中的“环境变量”,选中“系统变量”下的 Path 变量,依次点击“编辑”、“新建”和“浏览”,最后选择 Hugo 路径。结果如下:
在搜索栏输入
cmd
打开 Windows 终端,键入cd 路径
跳转到指定路径(直接拖动文件夹到终端,会显示相应的路径)。继续输入hugo new site 网站文件夹名
在该路径下生成网站文件夹。该文件夹包含了所有的源文件,主要是模板(archetypes,预设文章扉页)、内容(content,博客文章)、布局(layouts,自定义网页布局、样式和脚本等)、静态资源(static,文档、图片和视频等文件)、主题(themes,引用别人的布局)和配置文件(config.toml,用以全局管理整个网站)。上述操作如下:设计网站布局。刚接触 Hugo 的朋友建议使用主题。挑选合适的主题,下载解压到 themes 文件夹中,拷贝覆盖 exampleSite 内的文件(如果有的话)到根目录。打开配置文件,确保
theme = "主题文件夹名"
。在终端键入
cd 网站文件夹名 && hugo server
,点击出现的链接,例如http://localhost:1313/
,在浏览器中预览网站。而键入hugo
则会在 public 文件夹中生成一个完整的网站,但我们无需进行这个操作。关于其他命令可通过hugo --help
查看。每个主题的构建逻辑和配置方式不同,一般会有详细介绍,依葫芦画瓢即可。键入
hugo new 文件夹名/"标题.md"
在 content 目录下生成 Markdown 文档。打开后会看到扉页(front matter),用以填写标题、作者和链接等版权信息。以本文为例,输入hugo new zh/"静态网站搭建流程.md"
,然后设置扉页(可通过模板自动生成相关信息)--- title: "静态网站搭建流程" date: "2021-10-18T19:41:59+08:00" draft: true slug: "static website" description: "Introduction to build static website by Hugo, git action, cloud server, apache2." ---
若要公开文章,需要设置
draft: false
,或将其删除。推荐使用 Typora Markdown 写作,以及使用 VS Code 编辑网站。
GitHub
在本地写好博客之后,我们将源站推送(push)到 GitHub 上。
注册 GitHub,点击右上角加号新建一个仓库,确定仓库名,以及是否公开。
安装分布式版本控制软件 Git,然后在终端键入
git config --global user.name "GitHub 用户名" git config --global user.email "邮箱地址"
转到网站根目录
cd 网站根目录
,输入以下内容git init git add . git commit -m "first commit" git branch -M main git remote add origin 仓库链接 git push -u origin main
以上操作分别表示初始化仓库,添加所有内容到缓存区,提交,设置 main 为主分支,添加远程仓库,以及推送缓存区内容到 mian 分支。
需要注意的是,如果我们不想公开某篇文章,可以在扉页设置
draft: true
。但第三步依然会将该文档推送到仓库中。因此我们在网站根目录新建一个文件.gitignore
,令 Git 忽略特定的文件。例如,我将所有私密文章命名为文章名_d.md
,然后在 .gitignore 文件中添加*_d.md
,这样 git 在推送时会忽略所有以_d.md
结尾的文件。每次写好文章之后,只需要输入以下命令将其推送到远程仓库即可:
git add . git commit -m "该次推送说明" git push
关于 GitHub 的更多操作可参考官方文档。
服务器
在进一步设置 GitHub 前,我们先配置好服务器。
将域名解析到服务器 IP 地址。以
domain.com
和阿里云为例,设置记录类型为A
,主机记录为指定的二级域名@.domain.com
或三级域名(如www.domain.com
),解析线路默认,记录值为服务器 IP 地址,TTL 默认。远程登陆到云服务器,为了方便起见,
sudo su
进入管理员模式。安装和配置 apache2apt update apt -y upgrade apt install -y apache2
将 SSL 证书上传到服务器的
/etc/apache2/cert/
路径下,然后配置 apache2vim /etc/apache2/sites-available/blog.conf
按
i
进入编辑模式,并输入(假设网站位于/var/www/public/
目录下)<VirtualHost *:80> ServerName www.domain.com ServerAlias domain.com DocumentRoot /var/www/public <Directory /var/www/public/> Options +FollowSymlinks AllowOverride All SetEnv HOME /var/www/public SetEnv HTTP_HOME /var/www/public </Directory> # 设置 http 跳转到 https RewriteEngine on RewriteCond %{SERVER_PORT} !^443$ RewriteRule ^(.*)$ https://%{SERVER_NAME}$1 [L,R] </VirtualHost> <VirtualHost *:443> ServerName domain.com DocumentRoot /var/www/public SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM SSLHonorCipherOrder on # 以下三行为证书路径,请自行修改 SSLCertificateFile cert/domain.com_public.crt SSLCertificateKeyFile cert/domain.com.key SSLCertificateChainFile cert/domain.com_chain.crt # 设置 domain.com 域名跳转到 www.domain.com RewriteEngine on RewriteCond %{SERVER_NAME} =domain.com RewriteRule ^ https://www.%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent] </VirtualHost> #如果证书包含多个域名,复制以上参数,并将 ServerName 替换成第二个域名。 <VirtualHost *:443> ServerName www.domain.com DocumentRoot /var/www/public SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCipherSuite HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM SSLHonorCipherOrder on # 以下三行为证书路径,请自行修改 SSLCertificateFile cert/domain.com_public.crt SSLCertificateKeyFile cert/domain.com.key SSLCertificateChainFile cert/domain.com_chain.crt </VirtualHost>
完成后,按
Esc
输入:eq
保存退出。在终端输入a2ensite blog.conf ##使配置文件生效 systemctl reload apache2 ##重新加载 Apache 服务 a2enmod rewrite headers env dir mime ssl ##启用 ssl 模块 systemctl restart apache2 ##重启 Apache 服务
以上假设的域名为
www.domain.com
和domain.com
,并设置了后者自动跳转到前者。若需要设置www.domain.com
跳转到domain.com
,可参考这篇文章。安装同步软件:
apt install rsync
。生成 SSH 密钥,用以授权 GitHub 远程修改网站根目录
/var/www/public/
下的内容。ssh-keygen -t ed25519 -f ~/.ssh/blog_deploy_key cd ~/.ssh/ mv blog_deploy_key.pub authorized_keys cat blog_deploy_key
复制屏幕中出现的一长串密钥。
工作流
在 GitHub 仓库中点击 Settings、Secrets 和 New repository secret。添加 Name 为
BLOG_DEPLOY_KEY
,Value 为上一步生成的密钥。同理新增 Name:DIR
和 Value:/var/www/public
以及 Name:HOST
和 Value:服务器 IP 地址
。授权 Actions 自动运行工作流。依次点击 Settings 和 Actions,选择 Allow all actions,保存。
在 Windows 网站根目录下的 .github 文件夹中新建 workflows 文件夹。打开 workflows 新建 main.yml 文件,复制粘贴以下内容:
name: Deploy on push events on: push: branches: [ main ] # 在推送到 mian 分支时触发工作流 jobs: build: runs-on: ubuntu-18.04 # 服务器版本 steps: - name: Checkout uses: actions/checkout@v2 # 检出最新代码到虚拟环境中 with: submodules: 'recursive' fetch-depth: 0 # 拉取所有分支和标签的历史 - name: hugo uses: klakegg/actions-hugo@1.0.0 # 在虚拟环境中运行 hugo 生成网站到 public 文件夹中 with: command: --gc --minify image: ext-ubuntu pandoc_command: pandoc-default - uses: webfactory/ssh-agent@v0.4.1 with: ssh-private-key: | ${{ secrets.BLOG_DEPLOY_KEY }} # 读取 secrets 中 BLOG_DEPLOY_KEY 的值 - name: Scan public keys run: | ssh-keyscan ${{ secrets.HOST }} >> ~/.ssh/known_hosts # 匹配 secrets 中储存的密钥和服务器中的公钥 - name: Deploy run: | rsync -av --delete public root@${{ secrets.HOST }}:${{ secrets.DIR }} # 同步虚拟环境中的 public 文件夹内容和服务器中的 DIR 文件夹内容。
其中,我使用 pandoc 将 Markdown 文档转换为网页。对于其他主题,直接删除上面的
pandoc_command: pandoc-default
即可。推送本地内容到 GitHub,点击 GitHub 的博客仓库中的
Actions
,查看是否设置成功。