Blog小白的建站之路

想法始末

前一阵子,刚刚赶完论文,正是(游手好)闲的时候,看了电影,打了游戏,又出去玩了几趟。实在不知道还能做些什么打发时间,同时当作娱乐。偶然间看到同学的个人博客搭建的非常成功,非常羡慕,于是脑子一热,决定自己也来搭一个玩玩。

由于笨人🙃对前端技术一窍不通,也survey了各种方案:有考虑过前后端分离的模式,也有想过搭建纯前端的静态网页;有看过博客内容托管的服务,也有了解了域名、服务器的纯手搓方案……最后最后,我还是选择了用Gatsby的框架搭建一个纯前端的静态网页,然后自己买域名、买云服务器、编译、部署,主打的是一个头铁,全部自己完成。最后的效果就是现在这个样子了。接下来说说我在这个轻(jian)松(ku)的过程中遇到的一些个问题吧,也算是给增加一些知识储备。

关于域名、服务器

我是在腾讯云买的域名和服务器,总共花了240RMB,这是第一年的价格,后续会不会再涨价还不清楚,目前看来还是比较划算的。

我一开始想着,在腾讯云上设置一下,然后DNS把域名关联到我的机器上,再用nginx代理一下就结束了,可是事情远比想象的复杂。

首先是域名的问题,由于一开始在国内厂商买的域名,由于种种POLICY的原因,这个域名需要在网管局注册、备案,然后还要去公安部分进行审批,这是一个非常非常繁琐的流程,期间包括身份证的真人验证、客服打电话审批等过程,审批之后要经过漫长的等待,在这期间我的域名一直是不可访问状态,只能在本地看一下网站是什么情况。非常的痛苦。

然后是服务器的事情,这个服务器是在国内,走的也是国内的网络,然后就会遇到一个非常经典且🥚疼的问题:在这上边(几乎)无法正常访问Github、Docker、npm等各种境外服务,就要修改DNS,换源等一系列选择国外云服务厂商根本不会遇到的问题😇。

关于开发 & 编译

开发自然是在自己的电脑上进行的,最开始无脑配环境,一件brew安装nodejs,然后yarn install,Oops,问题出现。

由于我使用的模板是比较旧的版本的Gatsby,然后和最新的Nodejs@21是不太兼容的,后来经过一番探索,比较稳定能跑起来的版本是Nodejs@18,然后就换到了18上。这个倒是没有浪费很多时间,但是让人不太高兴==。想到JavaScript是世界上最烂的语言这一件事和Nodejs屎一样的依赖版本,最后还是换了docker,然后写了个Makefile一件编译、调试的事情,方便很多,而且不会让我的Mac变成一团乱麻。Docker,爽>_<!

current_dir := $(shell pwd)

install:
    docker run -it --rm -v $(current_dir):/app -w /app node:18 yarn install

build:
    docker run -it --rm -v $(current_dir):/app -w /app node:18 yarn build

format:
    docker run -it --rm -v $(current_dir):/app -w /app node:18 yarn format

run:
    docker run -it --rm -v $(current_dir):/app -w /app -p 8000:8000 node:18 yarn develop

clean:
    rm -rf node_modules/ public/ .cache/ yarn.lock package-lock.json

关于部署

这个是最最最头疼的事情!

在一开始,我打包好了静态资源,放在server上边,然后sudo systemctl restart nginx,兴冲冲打开浏览器一看404 Not Found,哈哈心态小崩😄。打开Log一看,全是Permission Denied,Google了一下,原来是Nginx基于权限最小化的准则,用一个特殊的user来运行,不过由于我的文件是放在另一个user的home目录下边,Nginx就没办法访问了。

那这个问题要怎么解决呢?有几种解决方案:

  1. 在Nginx的配置文件中,把user改成root,这样就可以访问到所有的文件了,但是这样做非常不安全(可能安全但是我觉得不太安全)。
  2. 使用chown命令,把文件的owner改成Nginx的user,这样也可以访问到文件了,不过这样每次部署都要手动改一下,还挺麻烦的。
  3. 第三种方案,就是我采用的方案:把文件放在用户的目录下边,然后用mount到一个Nginx可以访问到的地方,这样就可以访问到文件了。每次更新新的post时,也只用更新用户目录的文件,而不需要用一些sudo命令去做一些改变owner、修改权限的操作,very good👍。

以下是具体操作:

mount --bind -o rw /home/ubuntu/public /home/nginx/public

如果想在每次开机重启时,自动mount,也可以弄一个systemd的service,这样就可以自动mount咯(不过我没搞,下次再搞吧)。附上一个配置文件,/usr/sbin/bind-mounts放mount的脚本。

[Unit]
Description=Bind Mounts
After=local-fs.target

[Service]
Type=simple
ExecStart=/usr/sbin/bind-mounts

[Install]
WantedBy=multi-user.target

最后,为了每次push到Githu的时候可以进行自动部署,加了一个Github Action,这样每次push到master分支的时候,就会自动build,然后更新到服务器上,我只闷着头嘎嘎写Markdown就好😋。附上workflow的配置文件:

name: Node.js CI

on:
  push:
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x]

    steps:
      - name: Use ssh key
        run: |
          mkdir -p ~/.ssh
          echo "$DEPLOY_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

      - uses: actions/checkout@v3

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "yarn"

      - name: Install dependencies
        run: yarn install

      - name: Build
        run: yarn build

      - name: Upload Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-artifacts
          path: ./public

      - name: Copy files to remote server
        run: rsync -avz -e "ssh -o StrictHostKeyChecking=no" ./public/ myuser@myserver:~/public/

未来规划

接下来想做的的事情是,加一些回复功能,增加一些新的模块,比如搞个小的摄影集,也可能写写影评、文章什么的,欢迎长期关注!

鉴于目前还没有评论功能,所以如果有好的建议,欢迎邮件我:WangHaotian013@outlook.com,感谢支持!

Reference

  1. 解决个人用户目录做为 Web 服务根目录的权限问题-tangxinfa’s blog
  2. Github Actions