- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板 - 新增 Rust 快速参考指南 - 新增 Rust 后端工作流模板 - 优化 create-runner.md,明确 host 网络模式为缓存必需条件 - 更新 gitea skill 主文档
13 KiB
13 KiB
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"]
使用说明:
- 将
your-binary-name替换为实际的二进制文件名 - 修改
EXPOSE端口号 - 修改
HEALTHCHECK的端点和端口 - 在 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"]
使用说明:
- 将
your-binary-name替换为Cargo.toml中的[[bin]]name - 如果不需要 OpenSSL,可移除
openssl-dev - 修改端口和健康检查配置
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"]
使用说明:
- 将
your_binary_name替换为二进制文件名(下划线形式) - 适合本地
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/