PAYATHON 2026

如何创建预置文件内容的 rustfs Docker 容器?

技术老齐

集成测试中,可以先启动官方 RustFS 容器,再用一次性的 rc 容器创建桶并上传 my-config 中的文件,初始化成功后再运行测试。这样更省事,也无需在 docker build 阶段启动 RustFS。

这里的“预置”在测试启动阶段完成。如果测试文件还需要随镜像分发,可以把文件打包进初始化镜像。

为什么不能直接复制到 /data

/data 是 RustFS 管理的存储目录,存储对象时除了文件内容,还需要内部元数据。因此,COPY my-config /data/my-config 不能替代 S3 上传,也不应通过创建目录来创建桶、初始化测试环境。RustFS 存储操作说明

通过 S3 接口创建桶、上传对象,可以避免依赖底层存储格式。用 rc mb 和 rc cp --recursive 即可完成这两步;当前 CLI 也提供 rc bucket create 和 rc object copy 命令。桶命令参考、复制命令参考

用 Docker Compose 初始化测试数据

将 compose.yaml 放在 my-config 的同级目录:

.
├── compose.yaml
└── my-config/
    ├── app.json
    └── nested/
        └── rules.json

示例配置使用 latest,用于 CI 时应替换为经过验证的固定标签或镜像摘要。

services:
  rustfs:
    image: rustfs/rustfs:latest
    environment:
      RUSTFS_ACCESS_KEY: TESTACCESSKEY
      RUSTFS_SECRET_KEY: test-secret-key-change-me
      RUSTFS_ADDRESS: ":9000"
      RUSTFS_VOLUMES: /data
    ports:
      - "127.0.0.1:9000:9000"
    volumes:
      - rustfs-data:/data

  seed:
    image: rustfs/rc:latest
    depends_on:
      - rustfs
    volumes:
      - ./my-config:/seed:ro
    entrypoint: ["/bin/sh", "-ec"]
    command:
      - |
        attempts=0

        until rc alias set local http://rustfs:9000 \
            TESTACCESSKEY test-secret-key-change-me \
          && rc mb --ignore-existing local/my-config
        do
          attempts=$$((attempts + 1))
          if [ "$$attempts" -ge 60 ]; then
            echo "RustFS initialization failed" >&2
            exit 1
          fi
          sleep 1
        done

        rc cp --recursive /seed/ local/my-config/
        rc ls --recursive local/my-config/

volumes:
  rustfs-data:

RustFS 的凭据、监听地址和数据目录通过环境变量配置,数据存放在独立的 Docker 卷中。RustFS Docker 配置说明

依次执行:

docker compose up -d rustfs
docker compose run --rm seed

测试启动脚本应检查第二条命令的退出状态,只有返回 0 才继续运行测试。文件上传后的路径为:

my-config/app.json
    → s3://my-config/app.json

my-config/nested/rules.json
    → s3://my-config/nested/rules.json

宿主机上的测试使用 http://localhost:9000 作为 S3 endpoint,同一 Compose 网络中的测试容器则使用 http://rustfs:9000。测试使用的凭据应与配置一致,并按所用 SDK 的方式启用 path-style addressing。

这比构建时上传更合适的原因

原 Dockerfile 中的 sleep 3 假定 RustFS 能在三秒内就绪,CI 机器负载较高时容易失败。上述脚本会重试连接和创建桶,最多尝试 60 次;如果上传失败,初始化容器也会返回非零状态。

这里的 depends_on 只保证容器启动顺序,不能保证 S3 服务已经可用,所以仍然需要重试。

原命令用分号连接上传和 kill。即使上传失败,后面的 kill 仍可能成功,导致整个 RUN 被判定为执行成功。将初始化作为单独的测试前置步骤,更容易发现这类失败。

如果需要把测试文件打包进镜像

可以为 seed 单独准备一个 Dockerfile.seed:

FROM rustfs/rc:latest

COPY --chown=rc:rc my-config/ /seed/

然后将 Compose 中 seed 的 image 替换为:

    build:
      context: .
      dockerfile: Dockerfile.seed

同时删除 seed 的 volumes 配置,保留初始化命令。文件会随镜像分发,等 RustFS 启动后再导入,无需在构建阶段运行服务。

这段 Dockerfile 要求所选 rustfs/rc 镜像包含 rc 用户和 /bin/sh,固定镜像版本时应核对这两个条件。当前仓库的 Dockerfile 使用 Alpine,并创建了 rc 用户。CLI 镜像定义

测试结束后清理数据

递归复制不会自动删除桶中多余的对象。如果测试会修改数据,每轮测试应使用独立环境,或在结束后删除该项目的数据卷:

docker compose down -v

这条命令会删除上述 Compose 项目的测试数据。示例凭据也只适用于临时测试环境。

备注:内容仅供参考。