Rust 在 Linux 上的 CI/CD 实战方案
一、总体流程与关键检查
二、GitHub Actions 示例工作流
name: Rust CI/CD on Linux
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
- name: Cache Cargo
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Install sccache
run: cargo install sccache
- name: Configure sccache
run: |
echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
echo "SCCACHE_CACHE_SIZE=1G" >> $GITHUB_ENV
- name: Check formatting
run: cargo fmt -- --check
- name: Lint with Clippy
run: cargo clippy -- -D warnings
- name: Build
run: cargo build --release
- name: Run tests
run: cargo test --release -- --nocapture
- name: Upload binary
uses: actions/upload-artifact@v4
with:
name: app-linux-release
path: target/release/your-app-name
docker-build-push:
needs: build-test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ secrets.DOCKERHUB_USER }}/your-app:latest
- name: Scan image
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ secrets.DOCKERHUB_USER }}/your-app:latest
format: table
exit-code: 1
severity: CRITICAL
三、GitLab CI 与交叉编译
build-linux:
stage: build
image: ghcr.io/cross-rs/x86_64-unknown-linux-gnu:main-centos
variables:
OPENSSL_DIR: /usr
OPENSSL_INCLUDE_DIR: /usr/include
OPENSSL_LIB_DIR: /usr/lib64
PYO3_PYTHON: /opt/conda/bin/python3
script:
- cargo update
- cross build --release --target x86_64-unknown-linux-gnu
artifacts:
paths:
- target/x86_64-unknown-linux-gnu/release/your-app
expire_in: 1 week
四、容器化与 Kubernetes 部署
# Stage 1: build
FROM rust:1.70 as builder
WORKDIR /usr/src/app
COPY . .
RUN cargo build --release
# Stage 2: runtime
FROM debian:bullseye-slim
COPY --from=builder /usr/src/app/target/release/your-app /usr/local/bin/
USER 1000:1000
CMD ["your-app"]
apiVersion: apps/v1
kind: Deployment
metadata:
name: rust-app
spec:
replicas: 3
selector:
matchLabels:
app: rust-app
template:
metadata:
labels:
app: rust-app
spec:
containers:
- name: app
image: your-registry/your-app:latest
ports:
- containerPort: 8080
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
五、性能与安全最佳实践