- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板 - 新增 Rust 快速参考指南 - 新增 Rust 后端工作流模板 - 优化 create-runner.md,明确 host 网络模式为缓存必需条件 - 更新 gitea skill 主文档
9.4 KiB
9.4 KiB
Rust 项目 Gitea CI/CD 快速参考
快速设置 Rust 项目的 CI/CD 流程。
最小化配置(3 步)
1. 创建 Dockerfile.ci
在项目根目录创建 Dockerfile.ci:
FROM alpine:3.21
RUN apk add --no-cache ca-certificates tzdata curl && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app
COPY your-binary-name .
ENV TZ=Asia/Shanghai
ENV RUST_LOG=info
EXPOSE 9090
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -sf http://localhost:9090/healthz || exit 1
CMD ["./your-binary-name"]
修改项:
your-binary-name→ 你的二进制文件名(通常和Cargo.toml中的name一致)9090→ 你的服务端口
2. 创建 workflow 文件
创建 .gitea/workflows/your-service.yml:
name: Your Service - Build & Publish
on:
push:
paths:
- '**' # 修改为实际监听路径
tags:
- 'v*' # 修改为实际 tag 格式
env:
SERVICE_PREFIX: your-service # 修改为实际服务名
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
RUSTUP_DIST_SERVER: https://rsproxy.cn
RUSTUP_UPDATE_ROOT: https://rsproxy.cn/rustup
jobs:
build-and-publish:
runs-on: ubuntu-latest # 修改为你的 Runner 标签
steps:
- uses: actions/checkout@v4
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
source "$HOME/.cargo/env"
rustup target add x86_64-unknown-linux-musl
- name: Build
run: |
cargo build --release --target x86_64-unknown-linux-musl
cp target/x86_64-unknown-linux-musl/release/your-binary-name .
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ${{ github.server_url }}
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.RELEASE_TOKEN }}
- name: Build & Push Image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.ci
push: true
tags: |
${{ github.server_url }}/${{ github.repository }}:latest
${{ github.server_url }}/${{ github.repository }}:${{ github.sha }}
修改项:
your-service→ 你的服务名your-binary-name→ 你的二进制文件名ubuntu-latest→ 你的 Runner 标签paths→ 触发构建的路径tags→ 触发构建的 tag 格式
3. 推送代码并打 tag
git add .gitea Dockerfile.ci
git commit -m "ci: 添加 CI/CD 配置"
git push
# 触发构建
git tag v0.1.0
git push origin v0.1.0
进阶配置
添加交叉编译支持
如果你的 Runner 是 ARM64,但需要构建 x86_64 镜像:
- name: Install Zig and cargo-zigbuild
run: |
wget -q https://ziglang.org/download/0.13.0/zig-linux-aarch64-0.13.0.tar.xz
tar -xf zig-linux-aarch64-0.13.0.tar.xz
mv zig-linux-aarch64-0.13.0 /opt/zig
echo "/opt/zig" >> $GITHUB_PATH
cargo install cargo-zigbuild
- name: Build
run: |
cargo zigbuild --release --target x86_64-unknown-linux-musl
添加 Rust 缓存
- name: Cache Rust dependencies
uses: https://github.com/Swatinem/rust-cache@v2
with:
workspaces: . -> target
cache-targets: true
添加版本号注入
1. 创建 build.rs:
fn main() {
if let Ok(git_tag) = std::env::var("GIT_TAG") {
println!("cargo:rustc-env=GIT_TAG={}", git_tag);
}
println!("cargo:rerun-if-env-changed=GIT_TAG");
}
2. 在 workflow 中设置环境变量:
- name: Build
env:
GIT_TAG: ${{ github.ref_name }}
run: cargo build --release
3. 在代码中使用:
let version = option_env!("GIT_TAG").unwrap_or("dev");
println!("Version: {}", version);
添加 Release 创建
release:
name: Create Release
runs-on: ubuntu-latest
needs: build-and-publish
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Create Release
run: |
curl -X POST "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\": \"${{ github.ref_name }}\",
\"name\": \"Release ${{ github.ref_name }}\",
\"body\": \"自动构建的 Release\"
}"
健康检查端点实现
如果你的服务还没有健康检查端点,快速添加:
使用 Axum
use axum::{Router, routing::get};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/healthz", get(|| async { "OK" }));
let listener = tokio::net::TcpListener::bind("0.0.0.0:9090")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
使用 Actix-web
use actix_web::{web, App, HttpServer, HttpResponse};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/healthz", web::get().to(|| async { HttpResponse::Ok().body("OK") }))
})
.bind("0.0.0.0:9090")?
.run()
.await
}
使用 Rocket
#[macro_use] extern crate rocket;
#[get("/healthz")]
fn healthz() -> &'static str {
"OK"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![healthz])
}
Cargo.toml 优化配置
[profile.release]
opt-level = 3 # 最高优化级别
lto = true # 链接时优化
codegen-units = 1 # 单个代码生成单元
strip = true # 去除符号表
panic = 'abort' # panic 时直接退出
.dockerignore 示例
创建 .dockerignore 减小构建上下文:
target/
.git/
.gitignore
*.md
tests/
benches/
examples/
.github/
.gitea/workflows/
Dockerfile*
docker-compose.yml
环境变量配置
在 workflow 中
env:
RUST_LOG: info # 日志级别
CONFIG_FILE: production.yaml # 配置文件
DATABASE_URL: ${{ secrets.DATABASE_URL }} # 数据库连接
在 Dockerfile 中
ENV RUST_LOG=info
ENV CONFIG_FILE=production.yaml
在运行时
docker run -e RUST_LOG=debug -e CONFIG_FILE=custom.yaml your-image
常见 Runner 标签
| 标签 | 说明 |
|---|---|
ubuntu-latest |
Ubuntu 最新版本 |
darwin-arm64 |
macOS ARM64 |
darwin-amd64 |
macOS x86_64 |
linux-amd64 |
Linux x86_64 |
linux-arm64 |
Linux ARM64 |
查看可用 Runner:
/gitea-list-runners
触发条件参考
推送到特定分支
on:
push:
branches:
- main
- develop
推送特定路径
on:
push:
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
特定 tag 格式
on:
push:
tags:
- 'v*' # v1.0.0, v2.1.3
- 'device-rs-*' # device-rs-1.0.0
Pull Request
on:
pull_request:
branches:
- main
定时触发
on:
schedule:
- cron: '0 2 * * *' # 每天凌晨 2 点
调试技巧
查看 workflow 日志
在 Gitea 仓库页面:
- 点击 "Actions"
- 选择对应的 workflow run
- 查看每个 step 的日志
本地测试构建
# 测试 Rust 构建
cargo build --release --target x86_64-unknown-linux-musl
# 测试 Docker 构建
docker build -f Dockerfile.ci -t test:latest .
# 测试容器运行
docker run -p 9090:9090 test:latest
使用 act 本地运行 workflow
# 安装 act(如果使用 Gitea Actions)
# 注意:act 主要支持 GitHub Actions,Gitea Actions 可能有兼容性问题
# 列出可用的 actions
act -l
# 运行特定 job
act -j build-and-publish
完整配置示例
参考 BMS 项目的 device-rs:
- Workflow: device-rs.yml
- Dockerfile: Dockerfile.ci
- 项目结构: device-rs/
故障排查清单
构建失败
- 检查 Rust 版本是否满足要求
- 检查依赖是否正确(
Cargo.lock是否提交) - 检查 musl 目标是否安装(
rustup target list --installed) - 查看完整构建日志
Docker 推送失败
- 检查 Docker Registry 地址是否正确
- 检查
REGISTRY_USERNAME变量是否设置 - 检查
RELEASE_TOKENsecret 是否正确 - 检查 Token 权限(需要 packages write 权限)
容器启动失败
- 检查二进制文件名是否正确
- 检查端口是否正确
- 检查健康检查端点是否存在
- 查看容器日志(
docker logs <container>)
Runner 无法连接
- 检查 Runner 是否在运行(
/gitea-list-runners) - 检查 Runner labels 是否匹配 workflow 中的
runs-on - 检查网络连接
- 查看 Runner 日志(
~/.config/gitea/runners/<runner-name>/*.log)