〇、前言
很多个人项目,一开始的部署方式都比较简单:本地开发完了直接打包,上传到服务器直接运行。
后面项目变大后,打包时间变长了、包体积大了、传输也更费时了,就想着直接把代码上传服务器,在服务器打包运行不就完了!
所以部署方式又改为:本地开发提交推送,登录服务器更新代码然后部署运行。
时间久了,就感觉后面那步全是在重复劳动呀!作为一名程序员,怎么能够被重复劳动限制住手脚呢?
所以我决定,必须要实现自动化部署,而我,只需要push一下代码接即可。
一、优化思路
这里以自部署 Gitea 为例,使用:
Gitea Actions
act_runner
Docker Compose实现 push 后自动部署。
目标是把部署流程改成:
本地开发
→ git push 到 Gitea
→ Gitea Actions 自动触发
→ 服务器自动执行 docker compose 部署最终日常只需要 git push ,剩下的交给 Gitea Actions。
二、实现方案
这里选择一种最适合个人项目和单服务器项目的方式:
把 act_runner 直接安装在应用服务器上
也就是:
Gitea 仓库收到 push
→ Gitea Actions 触发任务
→ 应用服务器上的 act_runner 接收任务
→ 在服务器本机执行 docker compose这样就不需要 GitHub Actions,也不需要额外的 CI 服务器,也不需要 SSH 回应用服务器。
(一)开启 Gitea Actions
确认 Gitea 已经启用 Actions。
如果 Gitea 版本较老,需要在配置文件中开启:
[actions]
ENABLED=true然后进入仓库设置:
仓库 Settings
→ Actions
→ Enable Repository Actions(二)安装 act_runner
在应用服务器上创建目录:
mkdir -p /opt/act_runner
cd /opt/act_runner下载对应系统版本的 act_runnr,地址:https://gitea.com/gitea/act_runner/releases
赋予执行权限:
chmod +x act_runner
./act_runner --version生成配置文件:
./act_runner generate-config > config.yaml(三)注册 runner
在 Gitea 仓库页面获取 runner 注册 token:
仓库 Settings
→ Actions
→ Runners
→ Create new runner然后在服务器执行:
./act_runner register --no-interactive \
--instance https://你的-gitea-地址 \
--token 你的-registration-token \
--name prod-server \
--labels spring:host这里需要注意两个概念。
--name 是 runner 的名字,它只是显示用的。比如: prod-server 。
--labels 才是 workflow 里匹配 runner 用的标签,比如:spring:host 。
其中spring 是标签名,host 表示直接在宿主机执行(当然也有写 docker 的,那就是在 docker内运行)。
对应在 workflow 里应该写:
runs-on: spring(四)编写部署 workflow
在项目中创建文件:
.gitea/workflows/deploy.yml如果生产环境配置在服务器固定目录,比如 /srv/diary-dashboard,可以写成:
name: deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: spring
steps:
- uses: actions/checkout@v4
- name: Deploy
run: |
cd /srv/diary-dashboard
git pull
docker compose up -d --build不过更推荐让 workflow 使用当前 checkout 出来的代码进行构建,这样部署的 commit 会更明确。
(五)把 runner 做成系统服务
手动运行测试:
cd /opt/act_runner
./act_runner daemon --config config.yaml确认 Gitea 页面中 runner 在线后,再配置 systemd。
创建服务文件:
sudo nano /etc/systemd/system/act_runner.service写入:
[Unit]
Description=Gitea Actions runner
After=network.target docker.service
Requires=docker.service
[Service]
WorkingDirectory=/opt/act_runner
ExecStart=/opt/act_runner/act_runner daemon --config /opt/act_runner/config.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target启动服务:
sudo systemctl daemon-reload
sudo systemctl enable --now act_runner
sudo systemctl status act_runner三、可能遇到的问题
1. 提示没有匹配的 runner
如果页面提示:
没有匹配标签的在线 runner: spring说明注册 runner 时没有给其添加上我们想要的标签,可以手动给 act_runner 添加上标签。
在你的 config.yaml 里找 runner:,加上:
runner:
labels:
- "spring:host"然后重启服务使其生效:
sudo systemctl restart act_runner2. runner 权限问题
使用 host 类型 runner 时,要注意 runner 是由哪个用户运行的。
如果用 root 运行,虽然执行 Docker 和部署命令会比较方便,但权限过高。因为 host runner 会直接在宿主机执行 workflow 命令,一旦脚本有问题,影响范围会很大。另外,root 用户和你平时部署用的普通用户不是同一个环境,可能会丢失原来的 Git 凭据、SSH 配置、known_hosts 等,导致 git pull 或访问私有仓库失败。
如果用普通用户运行,则需要确保这个用户有足够的执行权限。例如:
1. 能执行 act_runner
2. 能读写 runner 工作目录
3. 能访问项目部署目录
4. 有 docker 执行权限其中 Docker 权限通常需要把该用户加入 docker 组:
sudo usermod -aG docker $USER所以更推荐使用专门的普通用户运行 runner,然后按需补齐目录权限和 Docker 权限。
总结
改造前的部署流程是:
本地 push
→ 登录服务器
→ git pull
→ docker compose up -d --build改造后变成:
本地 push
→ Gitea Actions 自动触发
→ 服务器上的 act_runner 自动部署对于个人项目项目来说,这种方式非常实用。
它不需要额外 CI 服务器,不需要复杂的镜像仓库流程,也不需要每次手动登录服务器。
只要 push 代码,Gitea Actions 就会自动把部署流程跑完。
后续如果项目变多,或者部署环境更复杂,还可以继续升级为:
Gitea Actions 构建 Docker 镜像
→ 推送到 Gitea Container Registry
→ 服务器 docker compose pull
→ docker compose up -d但对于起步阶段来说,Gitea Actions + act_runner + Docker Compose 已经足够把部署体验提升一大截。