Gitea Actions 实战:用 CI/CD 流水线自动部署你的 Laravel 项目
前言
前两篇文章我们把 Gitea 搭起来、学会了升级维护,但你可能觉得——这跟 GitHub 也没啥区别啊?
真正的差距在于:GitHub 有 Actions,能自动跑测试、自动部署代码。
好消息是:Gitea 1.21+ 自带 Actions 功能,跟 GitHub Actions 几乎一模一样,甚至兼容它的工作流文件格式。
这篇文章会用一个真实的 Laravel 项目做例子,带你走通从"推代码"到"自动部署"的全流程。
Gitea Actions 是什么?
简单来说,Gitea Actions 就是 Gitea 内置的 CI/CD 系统。你可以在仓库里放一个配置文件,当代码推送、创建 PR、打标签时自动执行一系列任务。
比如:
| 场景 | 自动干什么 |
|---|---|
推送代码到 master | 自动跑单元测试 + 代码规范检查 |
推送 v* 标签 | 自动构建并部署到生产服务器 |
| 创建 Pull Request | 自动跑集成测试,把结果贴到 PR 评论里 |
| 定时任务 | 每天凌晨自动备份数据库 |
两个核心概念:
- Workflow(工作流):放在仓库
.gitea/workflows/目录下的 YAML 配置文件,定义什么事件触发、跑什么任务 - Runner(运行器):负责实际执行工作流的程序,可以装在你的服务器上,也可以装在单独的机器上
第一步:启用 Gitea Actions
Gitea 1.21+ 默认开启了 Actions 功能。登录你的 Gitea 管理后台,检查一下:
- 进入「站点管理」→「设置」→「Actions」
- 确保 "启用 Actions" 是勾选状态
- 如果你用的是 1.21 之前的版本,先升级(上篇文章有教程)
确认开启后,我们下一步要装 Runner。
第二步:安装并注册 Runner
Runner 是真正干活的东西。可以理解成一台"打工机器"——Gitea 发出指令,Runner 执行。
2.1 下载 Runner
登录你的服务器(跟 Gitea 同一台就行),下载 Gitea Actions Runner:
# 创建目录
mkdir -p /opt/gitea-runner && cd /opt/gitea-runner
# 下载最新 runner
wget -O gitea-runner https://dl.gitea.com/act_runner/act_runner-linux-amd64
# 赋予执行权限
chmod +x gitea-runner2.2 在 Gitea 获取注册令牌
在浏览器里打开你的 Gitea:
- 点击右上角你的头像 → 「站点管理」
- 左侧菜单 → 「Actions」→ 「Runners」
- 点击 "创建 Runner"
- 复制显示的注册令牌(一串长字符串,类似
xxxxxxxxxx)
2.3 注册 Runner
回到服务器,执行注册命令:
# 注册(记得替换 URL 和 TOKEN)
./gitea-runner register \
--instance http://git.ay.lc:3000 \
--token 你的注册令牌 \
--name my-runner \
--labels ubuntu-latest:docker://node:20-bullseye参数说明:
| 参数 | 说明 |
|---|---|
--instance | 你的 Gitea 地址 |
--token | 上一步获取的注册令牌 |
--name | 给这个 Runner 起个名字 |
--labels | 声明 Runner 能跑什么环境,这里是 ubuntu-latest 标签 |
注册成功后,会在当前目录生成一个 .runner 配置文件。
2.4 启动 Runner
# 前台启动(先试一下能不能跑)
./gitea-runner daemon看到 Ctrl+C to stop 就说明成功了。按 Ctrl+C 停掉,我们把它做成服务。
# 创建系统服务
cat > /etc/systemd/system/gitea-runner.service << 'EOF'
[Unit]
Description=Gitea Actions Runner
After=docker.service
[Service]
ExecStart=/opt/gitea-runner/gitea-runner daemon
Restart=always
RestartSec=10
WorkingDirectory=/opt/gitea-runner
User=root
[Install]
WantedBy=multi-user.target
EOF
# 启动并设置开机自启
systemctl daemon-reload
systemctl start gitea-runner
systemctl enable gitea-runner
# 检查状态
systemctl status gitea-runner回到 Gitea 管理后台的 Runner 页面,你会看到你的 Runner 已经在线了 ✅
第三步:写你的第一个 Workflow
准备工作做完,来写真正的 CI/CD 流水线。
创建一个 Laravel 项目的自动测试工作流
假设你的 Gitea 上有一个 Laravel 项目仓库(比如聊天室项目 chatroom),你想在每次推送代码时自动跑测试。
在你的仓库根目录创建 .gitea/workflows/test.yml:
name: Laravel Tests
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: mbstring, pdo_mysql, xml, gd, redis
- name: 复制环境配置
run: cp .env.example .env
- name: 安装 Composer 依赖
run: composer install --no-interaction --prefer-dist
- name: 生成应用密钥
run: php artisan key:generate
- name: 运行 PHPUnit 测试
run: php artisan test把这个文件推送到仓库:
git add .gitea/workflows/test.yml
git commit -m "添加 Gitea Actions 自动测试工作流"
git push推送完成后,去 Gitea 仓库页面 → 「Actions」选项卡,你会看到一次新的运行正在执行。点进去可以看实时日志。
一个常见坑: Docker 环境下 composer install 可能会超时或内存不足。可以在 Runner 的 daemon 启动参数里加 --docker-network-mode host 来解决网络问题。
第四步:实战——自动部署到生产服务器
测试只是第一步,真正爽的是自动部署。
我们来实现一个工作流:推送 v* 标签(比如 v1.0.1)时,自动部署到生产服务器。
在你的仓库根目录创建 .gitea/workflows/deploy.yml:
name: Deploy to Production
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
- name: 设置 PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: mbstring, pdo_mysql, redis
- name: 安装依赖(生产环境)
run: |
composer install --no-interaction --prefer-dist --no-dev
npm ci --production
- name: 编译前端资源
run: npm run build
- name: 打包
run: |
tar -czf deploy.tar.gz \
--exclude='.git' \
--exclude='node_modules' \
--exclude='tests' \
--exclude='storage/logs/*' \
.
- name: 部署到服务器
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
port: ${{ secrets.DEPLOY_PORT }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
source: "deploy.tar.gz"
target: "/tmp"
- name: 远程执行部署脚本
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_HOST }}
username: ${{ secrets.DEPLOY_USER }}
port: ${{ secrets.DEPLOY_PORT }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
cd /www/wwwroot/chat.ay.lc
# 备份当前版本
cp -r . ../chat.ay.lc.bak
# 解压新版本
tar -xzf /tmp/deploy.tar.gz -C .
# 执行部署后操作
php artisan migrate --force
php artisan optimize
php artisan queue:restart
# 清理
rm /tmp/deploy.tar.gz
rm -rf ../chat.ay.lc.bak配置仓库 Secrets
上面的工作流用了 ${{ secrets.xxx }} 变量,你不能直接把服务器密码写在 YAML 文件里(不安全)。Gitea 提供了 Secrets 功能来安全存储敏感信息:
- 进入你的仓库 → 「设置」→ 「Actions」→ 「Secrets」
- 逐个添加以下 Secrets:
| Secret 名称 | 值 |
|---|---|
DEPLOY_HOST | 你的服务器 IP(比如 8.130.123.25) |
DEPLOY_USER | SSH 登录用户名(比如 root) |
DEPLOY_PORT | SSH 端口(比如 8898) |
DEPLOY_SSH_KEY | 你的 SSH 私钥(cat ~/.ssh/id_rsa 的内容) |
Secrets 存入后,任何人(包括你)在 Gitea 网页上都无法再查看明文,只能用在工作流里。密码学角度的原则是:密钥只在传输瞬间存在于内存中,永远不入日志。
触发部署
配置好后,推送一个标签:
# 打标签并推送
git tag v1.0.1
git push origin v1.0.1Gitea Actions 会自动触发部署工作流,跑到 deploy 那一栏你就能看到传输进度和部署日志。
第五步:玩点更高级的
多步骤并行加速
如果一个工作流里有多个互不依赖的任务,可以并行跑:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: php artisan test --parallel
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: PHP 代码规范检查
run: vendor/bin/pint --test
# 测试和规范检查都通过后,再部署
deploy:
needs: [test, lint]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
steps:
- run: echo "可以部署了!"发通知到飞书/钉钉/企业微信
工作流跑失败了,怎么第一时间知道?加个通知步骤:
- name: 发送飞书通知
if: failure()
uses: appleboy/telegram-action@v0.1.1
with:
# 这里换成你的 Webhook
webhook: ${{ secrets.FEISHU_WEBHOOK }}
message: |
❌ 部署失败!
仓库:${{ github.repository }}
分支:${{ github.ref }}
提交:${{ github.sha }}
查看详情:${{ github.server_url }}/${{ github.repository }}/actionsif: failure() 是关键——只有前置步骤失败时才发通知,不制造噪音。
定时任务(Cron)
Gitea Actions 也支持 Cron 定时触发:
on:
schedule:
# 每天早上 6 点备份数据库
- cron: '0 6 * * *'
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: 备份数据库
run: mysqldump -h ${{ secrets.DB_HOST }} -u ${{ secrets.DB_USER }} -p${{ secrets.DB_PASS }} myapp > backup.sql
- name: 上传到备份空间
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.BACKUP_HOST }}
username: ${{ secrets.BACKUP_USER }}
key: ${{ secrets.BACKUP_KEY }}
source: "backup.sql"
target: "/backup/$(date +%Y%m%d)"常见坑和解决方案
我在实际使用中踩过这些坑,列出来省你点时间:
Runner 连不上 Gitea
Failed to connect to gitea instance: dial tcp: connect: connection refused原因:Runner 用 localhost 连 Gitea,但 Gitea 只监听 0.0.0.0:3000 的 Docker 网络。
解决:注册时用 http://git.你的域名:3000 代替 localhost,或者 --instance http://宿主机IP:3000。
Docker 容器里 composer install 超时
The process '/usr/bin/composer' failed with exit code 5原因:Runner 默认的 Docker 容器没装 PHP/Composer。
解决:更换镜像标签为包含 PHP 的镜像,或者用一个自定义 Docker 镜像:
runs-on: ubuntu-latest
container:
image: serversideup/php:8.4-fpm-nginxSCP 传文件到服务器失败
dial tcp 8.130.123.25:22: connect: connection refused原因:你的 SSH 端口不是 22。
解决:appleboy/scp-action 有 port 参数,明确指定你的 SSH 端口:
- uses: appleboy/scp-action@v0.1.7
with:
port: ${{ secrets.DEPLOY_PORT }}工作流一直卡在 pending 状态
原因:Runner 离线了,或者没有匹配的标签。
检查:
systemctl status gitea-runner如果离线了,重启 Runner,去管理后台确认在线状态。
写在最后
有了 Gitea Actions,你的 Gitea 就从"私有的 GitHub"升级成了"私有的 GitHub + GitLab CI"。每次推代码都会自动跑测试、自动部署,再也不用 SSH 到服务器手动敲命令了。
回顾一下整篇文章:
- ✅ 启用 Gitea Actions
- ✅ 安装并注册 Runner
- ✅ 写 Laravel 自动测试工作流
- ✅ 实现标签推送自动部署
- ✅ 多步骤并行 + 失败通知 + 定时任务
从第一篇的"搭起来",到第二篇的"管好它",再到今天的"让它帮你干活"——你的 Gitea 已经成为一个完整的 DevOps 平台了。
下期预告:Gitea + Docker Registry 搭建私有镜像仓库,敬请期待~
版权声明:本文为原创文章,版权归 放飞的流星 所有,转载请联系博主获得授权。
本文地址:https://ay.lc/h/Gitea-Actions-CI-CD-Laravel.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。