把廉价香橙派利用到极致,跑自建 Gitea 和 Hexo 服务
这篇文章在我的博客同步发布:把廉价香橙派利用到极致,跑自建 Gitea 和 Hexo 服务
书接上回 code-server 搭建。code-server 因为是原生服务,再加上这枚 H618 芯片性能相当可以,内存和 CPU 占用都很小,但是耗电却紧压电源适配器的 15 W 极限,剩余的性能……浪费了?
这怎么行?!
经过苦思冥想,我找到了另外一些有意思的功能。
1. 还能再干啥?
ARM 单片机有一个很严重的问题,就是软件不兼容。大部分 Debian 软件仓库的包都是在 x86_64 和 ARM 的兼容层上运行的,这会导致性能损失;部分重度依赖处理器架构(例如用特殊的指令集)的包,干脆就没有 ARM 版本。
很多服务,从博客平台到 Git 服务到代理,都依赖数据库。但是数据库为了性能,往往都会采用上述的指令集,所以基本上都不大好移植。我经过查找,发现只有 PostgreSQL 在 ARM 架构下有原生版本,安装起来也很容易:
sudo apt install postgresql postgresql-contrib
但是 PostgreSQL 的管理方式与 MySQL 和 MariaDB 都很不一样,所以我也花了很长时间才适应它的特殊方法,下面因为我们只需要一小部分手动步骤,其他都是由现成的软件操作的,所以不必担心。
那么,话说回来,我们现在有了数据库,能干啥?我第一个想到的是自建 Git 服务,毕竟我对于多端同步和(自己跟自己)协同开发还是很有需求的,而 GitHub 由于不可描述的原因在国内非常慢(我不可能保证所有地方都有代理),Gitee 嘛……用过的都说好。
目前常见的开源自建 Git 服务,最著名的是功能极其丰富、适合大型项目(Arch Linux、KDE 等等)、超大规模团队、因此资源占用非常高的 GitLab CE(Community Edition)。我这小 ARM 主机吃不消,放弃。
然后选择就不多了。刷刷 Reddit,大家普遍推荐的有 Gitea、Gogs 等等,在性能与功能以及与 GitHub 服务(Action、CI/CD 之类的)的兼容性等的考虑下,我选择了 Gitea。
另外一个我很想本地运行的服务是博客。虽然 Netlify 很好,但是最近不知为何它家的 CDN 在国内变得非常慢,我的博客因为资源太多,加载不出来。如果能在国内运行一个博客,那就能直接绕过这个问题。但是大家都知道,云主机很贵,备案很麻烦,所以内网穿透,虽然无法被搜索引擎收录,十分好用。
2. Gitea
先装 Gitea。Gitea 有很丰富的文档,大家可以自行查看。这里我就不解释很多了,就说说步骤和坑点。
首先在下载页找到最新的版本,例如现在是 1.21.1,然后用 wget 下载类似 gitea-1.22.1-linux-arm64 这样的文件,授予权限(chmod +x gitea-1.22.1-linux-arm64
),然后别着急运行。
按照文档,我们需要建立用户 git 和一些目录结构:
adduser \
--system \
--shell /bin/bash \
--gecos 'Git Version Control' \
--group \
--disabled-password \
--home /home/git \
git
mkdir -p /var/lib/gitea/{custom,data,log}
chown -R git:git /var/lib/gitea/
chmod -R 750 /var/lib/gitea/
mkdir /etc/gitea
chown root:git /etc/gitea
chmod 770 /etc/gitea
注意需要使用 root 运行。需要注意的是官方文档给出的是创建一个没有密码的 git 账户,如果后期需要登录 git,就会遇到问题。在安装完成之后,我们可以通过 passwd git
来设置一个密码。
然后,还是不要着急。我们刚刚只是安装了数据库,并没有创建 Gitea 所需的数据库和账户。PostgreSQL 与 MySQL 不一样,使用一个专门的 postgres(在安装时已经创建的)账户来管理数据库。
su - postgres
psql
此时我们会进入由“#”提示的管理员账户,有一个 PostgreSQL 的交互终端。
create user gitea with password "[SOME_PASSWORD]";
create database gitea;
grant all on gitea to gitea;
alter database owner to gitea;
注意 SQL 要求每一行末尾都必须要有分号,并且命令部分对大小写不敏感,但是数据部分(gitea
和 密码)是大小写敏感的。并且另外一个与 MySQL 不一样的地方是,grant *.* on
和 grant all on
是不一样的,前者只是允许其修改所有内容,后者还赋予了其他管理权限;另外 alter
这一行是必须的,否则之后会出现权限问题。
根据 Gitea 的文档,建议是将二进制文件移动到一个全局的位置:
sudo cp gitea /usr/local/bin/gitea
如果使用防火墙,记得开放 3000 端口:
sudo firewall-cmd --permanent --zone=public --add-port=3000/tcp
为了更加方便和安全地管理 Gitea,我们可以为它添加一个 Systemd 单元文件,sudo nano /etc/systemd/system/gitea.service
。
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
Wants=postgresql.service
After=postgresql.service
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
[Install]
WantedBy=multi-user.target
注意这里为了简洁,我删除了我们不需要的所有配置,如果有特别的要求,可以查看 Gitea 的示例。
然后启动服务:
sudo systemctl daemon-reload
sudo systemctl enable --now gitea
这时候我们去访问 [IP]:3000
,应该就可以看到安装界面了!
安装页面上,我们主要要填写的是数据库的配置。上面我们已经设置好了,按照这个填写:
数据库类型:PostgreSQL
数据库主机:(保持默认)
用户名:gitea
密码:(刚刚设置的)
数据库名称:gitea
字符集:(保持默认)
下面的额外设置都很好理解,这里就不赘述了,唯一要提一下的是,如果你打算把 Gitea 暴露到外网,建议设置一下需要验证邮箱,并且发件信息也需要填写,用 Outlook 可以是:
SMTP 服务器:stmp-mail.outlook.com
端口号:587
用户名:(Outlook 邮箱)
密码:(微软账号密码)
完成设置,可以点击“安装”!
不出意外,这时候应该出现一杯茶慢慢填满的安装画面,大约 1 分钟之后 Gitea 的界面就会出现了!
如果出了意外,建议将以上步骤尤其是数据库部分仔细检查,是否跳过步骤。有些错误是不可以忽略的。
如果你用内网穿透打算把 Gitea 暴露到公网,记得修改一下 /etc/gitea/app.ini
里 ROOT_URL
的值,为你的内网穿透地址,否则在存储库页面上,复制的地址都是错误的(192.168.?.?:3000
)。
其他的操作,甚至包括 Gitea Actions,都是和 GitHub 非常相似的,并且在网上可以找到很多教程,相信你可以自己完成。
3. 博客
博客就非常简单的。这里将使用 Hexo 作为示例,但如果你使用 Hugo 等其他框架,也是一样的,只需要用你的方法将生成的静态文件复制即可,下面会讲到。
首先我们既可以在刚刚建立的 Gitea 上搭建存储库,也可以就在 GitHub 上,总之你现在需要一个 Git 存储库。下面存储库的地址以 [REPO_URL]
代替。
在本地(或者服务器,如果你之间建立了 code-server 的话)找一个风水宝地,拉取一份代码。
git clone [REPO_URL]
然后进入目录,并打开终端:
sudo pacman -S nodejs npm # 更换为你的发行版
sudo npm install -g hexo-cli
由于 git 存储库和 Hexo 都要求初始化目录必须是空的,所以我们暂时先另外找一个目录初始化 Hexo。
hexo init ./some-dir
cp -r ./some-dir/* [REPO_NAME]
(这里我们假设你使用 Linux;如果是 Windows 请自行查找 Hexo 文档。)
然后我们检查一下,在 git 存储库里应该已经出现了 Hexo 的文件。我们添加一下 .gitignore
,避免二进制文件目录 node_modules
被上传。
在这个目录里,我们可以使用以下命令检查是否正常安装:
hexo g && hexo s && hexo clean
这个命令会生成静态页面,并在 4000 端口上开始作为服务器运行。按照上文提及的方法打开防火墙,在浏览器中输入 [IP]:4000
,应该就可以看到默认的 Landscape 主题和一篇 hello-world 测试文档了。
大家可以自行到 Hexo 的主题中找一个中意的,按照说明安装,其他的操作方法 Hexo 有详细的文档,还有中文,这不是本文的重点,请大家自行摸索。
接下来我将用一个不是那么优雅的方法实现更新。由于 Git Hooks 的方法不是特别适用于我们的情况,可以新建一个 Bash 脚本,在每次推送文章的时候手动执行一次。考虑到写一篇文章(以及咕咕)需要很长时间,这好像也不是特别烦对吧……
我们先安装服务器 nginx:
sudo apt install nginx
修改配置:
sudo mkdir /var/www/html/blog
sudo nano /etc/nginx/conf.d/blog.conf
# nano 中输入
server {
listen 8001;
server_name [IP];
root /var/www/html/blog;
index index.html;
}
以上配置中将网页端口给了非常规的 8001,如果大家是在(真正的)服务器上安装可以改为 80,我们这里打算内网穿透,所以 8001 反而不容易冲突。
(记得打开防火墙。我不记得我第几次说这个了……下文所有端口大家自己记得打开吧。)
nginx 配置到此结束。接下来我们写一个 Bash 脚本:
sudo nano /opt/blog-deploy
# nano 界面中
# 以下这一行 `#!/bin/bash` 绝对不可省略。这告诉系统使用 bash 执行。
#!/bin/bash
set -e
rm -rf /tmp/blog*
REPO_PATH="/tmp/blog.$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c10)"
git clone "[REPO_URL]" $REPO_PATH
cd $REPO_PATH
npm install
hexo g
rm -rf /var/www/html/blog/*
cp -r public/* /var/www/html/blog
systemctl restart nginx
我们将把所有临时文件放在 /tmp/blog[随机 10 个字符]
中,每次推送时删除上次的临时文件,在这个文件夹内我们会完成所有依赖包、生成的工作,将结果复制到刚刚提到的目录中。
这个命令由于每次都要初始化 NPM 的包,所以事件比较长,直接在终端上运行会比较麻烦,也可以(更加不优雅地)用 Systemd 管理。
(你就说能不能用吧。)
sudo nano /etc/systemd/system/blog.conf
# nano 界面中
[Unit]
Description=Blog
After=network.target
[Service]
Type=simple
User=root
ExecStart=/opt/blog-deploy
[Install]
WantedBy=multi-user.target
这样我们只需要 sudo systemctl start blog-deploy
就可以开始部署了,然后可以关闭终端,等 10 分钟左右,看看,应该就部署好了。
4. 结语
好的那么我们往我们的小香橙派上又添加了两个服务。但是根据我测试,如果 Gitea 没有跑 Actions 或者提交 push 的时候,其实性能还是冗余的,如果打开 code-server 网页,CPU 占用会上来一点。那么这给我们一个启示:由于我们的情况并发量很小,其实我们可以部署很多服务,反正每次都用一个,实现全部本地化。
至于什么时候写接下来的代码……以后再说吧。(咕咕。)