Files
voson 425ca5b5fd feat(gitea): 添加 Dockerfile 模板和 Rust 支持,优化 runner 网络配置说明
- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板
- 新增 Rust 快速参考指南
- 新增 Rust 后端工作流模板
- 优化 create-runner.md,明确 host 网络模式为缓存必需条件
- 更新 gitea skill 主文档
2026-01-30 10:12:09 +08:00

13 KiB
Raw Permalink Blame History

Rust 服务 Dockerfile 模板

Rust 项目的 Docker 容器化模板,支持多种构建场景。

模板类型

1. CI 构建镜像Dockerfile.ci

适用场景:在 CI/CD 中使用,二进制文件已在外部构建完成。

优点

  • 镜像体积最小(~20MB
  • 构建速度快
  • 适合生产环境
FROM alpine:3.21

# 安装运行时依赖
RUN apk add --no-cache ca-certificates tzdata curl && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

WORKDIR /app

# 复制编译好的二进制文件(由 CI workflow 构建)
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"]

使用说明

  1. your-binary-name 替换为实际的二进制文件名
  2. 修改 EXPOSE 端口号
  3. 修改 HEALTHCHECK 的端点和端口
  4. 在 CI workflow 中先构建二进制,再构建镜像

2. 完整构建镜像Dockerfile

适用场景:本地开发、无 CI 环境、独立构建。

优点

  • 自包含构建流程
  • 可在任何环境构建
  • 利用 Docker 缓存加速
# ============================================
# 构建阶段
# ============================================
FROM rust:1.83-alpine AS builder

# 安装构建依赖
# musl-dev: musl libc 开发包(静态链接)
# openssl-dev: OpenSSL 开发包(如果项目依赖 openssl
# pkgconfig: pkg-config 工具
RUN apk add --no-cache musl-dev openssl-dev pkgconfig

# 配置 Cargo 镜像加速(使用 rsproxy.cn
RUN mkdir -p /root/.cargo && \
    echo '[source.crates-io]' > /root/.cargo/config.toml && \
    echo 'replace-with = "rsproxy-sparse"' >> /root/.cargo/config.toml && \
    echo '[source.rsproxy-sparse]' >> /root/.cargo/config.toml && \
    echo 'registry = "sparse+https://rsproxy.cn/index/"' >> /root/.cargo/config.toml

WORKDIR /build

# 先复制依赖文件,利用 Docker 层缓存
# 只要 Cargo.toml 和 Cargo.lock 不变,依赖层就会被缓存
COPY Cargo.toml Cargo.lock ./

# 创建虚拟 src 目录,预先下载和编译依赖
# 这样修改源码时不需要重新编译依赖
RUN mkdir src && \
    echo "fn main() {}" > src/main.rs && \
    cargo build --release --target x86_64-unknown-linux-musl && \
    rm -rf src

# 复制实际源码
COPY src ./src

# 构建 Release 版本musl 静态链接)
RUN cargo build --release --target x86_64-unknown-linux-musl

# ============================================
# 运行阶段
# ============================================
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 --from=builder /build/target/x86_64-unknown-linux-musl/release/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"]

使用说明

  1. your-binary-name 替换为 Cargo.toml 中的 [[bin]] name
  2. 如果不需要 OpenSSL可移除 openssl-dev
  3. 修改端口和健康检查配置

3. 依赖缓存优化版Dockerfile.cache

适用场景:本地开发,频繁构建。

优点

  • 最大化利用缓存
  • 依赖只编译一次
  • 适合迭代开发
# ============================================
# 依赖缓存阶段
# ============================================
FROM rust:1.83-alpine AS dependencies

RUN apk add --no-cache musl-dev openssl-dev pkgconfig

# 配置 Cargo 镜像
RUN mkdir -p /root/.cargo && \
    echo '[source.crates-io]' > /root/.cargo/config.toml && \
    echo 'replace-with = "rsproxy-sparse"' >> /root/.cargo/config.toml && \
    echo '[source.rsproxy-sparse]' >> /root/.cargo/config.toml && \
    echo 'registry = "sparse+https://rsproxy.cn/index/"' >> /root/.cargo/config.toml

WORKDIR /build

# 只复制依赖文件
COPY Cargo.toml Cargo.lock ./

# 创建虚拟 main.rs编译依赖
RUN mkdir -p src && \
    echo "fn main() {}" > src/main.rs && \
    cargo build --release --target x86_64-unknown-linux-musl

# 删除虚拟源码编译产物
RUN rm -f target/x86_64-unknown-linux-musl/release/deps/your_binary_name*

# ============================================
# 构建阶段
# ============================================
FROM rust:1.83-alpine AS builder

RUN apk add --no-cache musl-dev openssl-dev pkgconfig

WORKDIR /build

# 从依赖阶段复制编译缓存
COPY --from=dependencies /root/.cargo /root/.cargo
COPY --from=dependencies /build/target target

# 复制所有文件
COPY . .

# 构建项目
RUN cargo build --release --target x86_64-unknown-linux-musl

# ============================================
# 运行阶段
# ============================================
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 --from=builder /build/target/x86_64-unknown-linux-musl/release/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"]

使用说明

  1. your_binary_name 替换为二进制文件名(下划线形式)
  2. 适合本地 docker build 使用

4. 多平台构建版Dockerfile.multiarch

适用场景:需要支持 ARM64 和 AMD64。

# ============================================
# 构建阶段(支持多平台)
# ============================================
FROM --platform=$BUILDPLATFORM rust:1.83-alpine AS builder

# 安装构建依赖
RUN apk add --no-cache musl-dev openssl-dev pkgconfig clang

# 配置 Cargo 镜像
RUN mkdir -p /root/.cargo && \
    echo '[source.crates-io]' > /root/.cargo/config.toml && \
    echo 'replace-with = "rsproxy-sparse"' >> /root/.cargo/config.toml && \
    echo '[source.rsproxy-sparse]' >> /root/.cargo/config.toml && \
    echo 'registry = "sparse+https://rsproxy.cn/index/"' >> /root/.cargo/config.toml

# 安装目标架构支持
ARG TARGETARCH
RUN case "$TARGETARCH" in \
      "amd64") echo "x86_64-unknown-linux-musl" > /target.txt ;; \
      "arm64") echo "aarch64-unknown-linux-musl" > /target.txt ;; \
      *) echo "Unsupported architecture: $TARGETARCH" && exit 1 ;; \
    esac && \
    rustup target add $(cat /target.txt)

WORKDIR /build

COPY Cargo.toml Cargo.lock ./
COPY src ./src

# 构建对应架构
RUN cargo build --release --target $(cat /target.txt)

# 复制二进制到统一路径
RUN mkdir -p /app && \
    cp target/$(cat /target.txt)/release/your-binary-name /app/

# ============================================
# 运行阶段
# ============================================
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 --from=builder /app/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"]

使用说明

# 构建多平台镜像
docker buildx build --platform linux/amd64,linux/arm64 -t your-image:latest .

高级配置

健康检查配置

# 存活探针Liveness Probe
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD curl -sf http://localhost:9090/healthz || exit 1

# 参数说明:
# --interval=30s       每 30 秒检查一次
# --timeout=5s         单次检查超时 5 秒
# --start-period=10s   容器启动后 10 秒开始检查
# --retries=3          失败 3 次后认为不健康

多端点健康检查

# 使用脚本检查多个端点
RUN echo '#!/bin/sh' > /healthcheck.sh && \
    echo 'curl -sf http://localhost:9090/healthz || exit 1' >> /healthcheck.sh && \
    echo 'curl -sf http://localhost:9090/readyz || exit 1' >> /healthcheck.sh && \
    chmod +x /healthcheck.sh

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD ["/healthcheck.sh"]

环境变量配置

# 基础环境变量
ENV TZ=Asia/Shanghai
ENV RUST_LOG=info
ENV RUST_BACKTRACE=1

# 应用配置(可在 docker run 时覆盖)
ENV CONFIG_FILE=production.yaml
ENV HTTP_PORT=9090
ENV LOG_LEVEL=info

# 数据库配置(敏感信息应通过运行时注入)
# ENV DATABASE_URL=postgresql://...

非 root 用户运行

# 创建非特权用户
RUN addgroup -g 1000 appuser && \
    adduser -D -u 1000 -G appuser appuser

WORKDIR /app

# 复制二进制文件
COPY --from=builder /build/target/x86_64-unknown-linux-musl/release/your-binary-name .

# 修改所有权
RUN chown -R appuser:appuser /app

# 切换用户
USER appuser

CMD ["./your-binary-name"]

配置文件挂载

# 在 Dockerfile 中创建配置目录
RUN mkdir -p /app/configs /app/logs

# 在 docker run 时挂载
# docker run -v ./configs:/app/configs -v ./logs:/app/logs your-image

构建命令示例

本地构建

# 基础构建
docker build -t your-service:latest .

# 指定 Dockerfile
docker build -f Dockerfile.ci -t your-service:latest .

# 传递构建参数
docker build --build-arg GIT_TAG=1.0.0 -t your-service:1.0.0 .

# 查看构建过程
docker build --progress=plain -t your-service:latest .

多平台构建

# 创建 buildx builder
docker buildx create --name mybuilder --use

# 构建并推送
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t registry.example.com/your-service:latest \
  --push \
  .

优化构建速度

# 使用 BuildKit 缓存
export DOCKER_BUILDKIT=1

# 使用外部缓存
docker build \
  --cache-from=type=registry,ref=your-service:buildcache \
  --cache-to=type=registry,ref=your-service:buildcache,mode=max \
  -t your-service:latest \
  .

镜像大小优化

1. 使用 Alpine 基础镜像

# Alpine 镜像体积小(~5MB
FROM alpine:3.21

2. 静态链接musl

# 构建时使用 musl 目标,生成静态链接二进制
RUN cargo build --release --target x86_64-unknown-linux-musl

3. Strip 二进制文件

# Cargo.toml
[profile.release]
strip = true  # 去除符号表

或在 Dockerfile 中:

# 手动 strip
RUN strip target/x86_64-unknown-linux-musl/release/your-binary-name

4. 最小化层数

# 合并多个 RUN 命令
RUN apk add --no-cache ca-certificates tzdata curl && \
    ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    addgroup -g 1000 appuser

5. 使用 .dockerignore

# .dockerignore
target/
.git/
.gitignore
*.md
tests/
benches/

安全建议

1. 使用特定版本标签

# 不推荐:使用 latest
FROM alpine:latest

# 推荐:使用特定版本
FROM alpine:3.21

2. 定期更新依赖

# 更新 Cargo 依赖
cargo update

# 检查安全漏洞
cargo audit

3. 最小权限原则

# 使用非 root 用户
USER appuser

# 只读文件系统(根据需要)
# docker run --read-only your-service

4. 不在镜像中包含敏感信息

# 错误示例
# ENV DATABASE_PASSWORD=secret123

# 正确做法:通过运行时注入
# docker run -e DATABASE_PASSWORD=secret123 your-service

常见问题

Q1: 镜像体积过大

原因

  • 使用 rust:latest 作为运行镜像(>1GB
  • 没有使用多阶段构建
  • 包含 debug 符号

解决方案

# 使用多阶段构建 + Alpine
FROM rust:1.83-alpine AS builder
# ... 构建步骤 ...

FROM alpine:3.21  # 最终镜像只有 ~20MB
COPY --from=builder /build/target/.../your-binary .

Q2: openssl 链接错误

错误信息

error: linking with `cc` failed
ld: library not found for -lssl

解决方案

# 方案 1安装 openssl-dev
RUN apk add --no-cache openssl-dev

# 方案 2使用 rustls 替代 openssl
# 在 Cargo.toml 中使用 rustls feature

Q3: 交叉编译失败

错误信息

error: linker `aarch64-linux-musl-gcc` not found

解决方案

# 安装 musl 交叉编译工具链
rustup target add aarch64-unknown-linux-musl

# 或使用 cargo-zigbuild
cargo install cargo-zigbuild
cargo zigbuild --target aarch64-unknown-linux-musl

Q4: 容器启动失败

检查步骤

# 查看日志
docker logs your-container

# 进入容器调试
docker run -it --entrypoint /bin/sh your-image

# 检查二进制是否可执行
docker run your-image ls -lh /app/

参考资源