记录本地Gitea Actions部署Hexo博客的过程
前言
我的Hexo博客目前是托管在云服务器上的,所以需要在写完文章后,将最新生成的静态文件上传到服务器对应目录下,这次选择用本地自建的Gitea仓库来完成自动化更新部署操作。
Gitea Workflows配置
Gitea Actions兼容GitHub Actions,所以在本地Gitea Workflows配置文件里面可以直接使用已有的GitHub Actions,你的本地Gitea实例需要能够访问GitHub,拉取对应的GitHub Actions代码。Gitea的部署和Gitea Runner的部署,请参考官方文档,写的很清楚,而且Docker化部署很简单,没有难度,只要你能连得上Docker Hub就行。
整个部署流程大致分为以下几步:
- checkout到当前仓库
- 设置
node.js版本 - 安装Hexo以及依赖
- 本地生成静态文件
- 上传到Web服务器目录
在安装Hexo以及依赖的时候,遇到了npm的权限问题,将$HOME下的.npm目录所有者修改为$USER后就没问题了,推测是安装npm的GitHub Actions安装之后,创建的.npm目录所有者不是$USER。
上传到Web服务器目录使用的是easingthemes/ssh-deploy@main这个GitHub Actions,通过rsync来完成文件的上传,完整的deploy.yml内容如下:
1 | name: Deploy Hexo Blog |
其中${{ secrets.REMOTE_HOST }}这些变量在Gitea仓库设置的Actions部分通过密钥添加,添加完毕后会自动调用设置好的密钥,在日志里面不会明文显示。
把编辑好的deploy.yml放到.gitea/workflows目录下,然后push到Gitea仓库,如果runner和Gitea仓库设置正确,就可以在Actions标签页看到正在运行的Actions任务了。
服务器设置
Debian服务器里面就有一个用户debian,所以在delpoy.yml的REMOTE_USER填的也是这个用户。首先将debian用户添加到www-data用户组:
1 | sudo gpasswd -a "$USER" www-data |
然后将用户目录里面的博客静态文件目录与网站目录做一个软连接,这样就不用直接在网站目录里面上传修改文件,提高了安全性,省去了很多权限问题。
1 | sudo ln -sT ~/path/to/blog /path/to/serve/blog |
顺带将blog的父目录所属用户组也改为www-data,权限修改为710,这样做的好处是如果以后有其他的项目,也可以比较方便的建立软连接。
1 | sudo chgrp www-data ~ ~/path/to |
最后是修改用户目录下的静态文件目录所属用户组,让www-data用户组可以读取和写入文件:
1 | sudo chgrp www-data ~/path/to/blog |
添加一个新的nginx配置,/etc/nginx/sites-available/your.blog,内容如下:
1 | server { |
先删掉nginx的默认配置:
1 | sudo rm /etc/nginx/sites-enabled/default |
然后为刚才添加的站点添加软连接:
1 | ln -s /etc/nginx/sites-available/your.blog /etc/nginx/sites-enabled |
确认一下软连接是否成功:
1 | ls -lash /etc/nginx/sites-enabled |
最后测试一下添加的nginx配置文件,没有报错的话,重启一下nginx服务就好了:
1 | sudo nginx -t |
如果一切顺利,应该可以通过http://www.your.blog打开你的博客了。SSL证书我选择的还是最方便快捷的cerbot,只要你的服务器能够正常访问cerbot,那就非常简单了,不在此赘述,nginx配置也会自动添加相应的内容以及http跳转。
总结
之前用Webhook调用本地部署脚本来在服务器端生成静态文件,遇到了很多问题,加上甲骨文直接连号带服务器一起封了,现在又只能用1C1GB的AMD服务器,就决定只让服务器来托管静态文件,静态文件生成放在本地比较好。用Gitea Actions有更好的日志支持,方便出问题了调试,整个流程还是比较简单的,关键还是本地Gitea实例的搭建和内网穿透,让云服务器和本地可以顺畅的传输数据。我目前是用的Tailscale来打通云服务器和本地NAS服务器,虽然云服务器和NAS服务器都分配了IPv6地址,但是ssh deploy这个actions好像在调用rsync的时候没有办法正常识别云服务器的IPv6地址,一直不成功,以后再折腾吧。