他の方に作ってもらったRustのRockerを使ったAPIをARM64/AMD64用のコンテナにしたくなったのでDockerfileがない状態からなんとかした話。
前提
-
- 開発環境: Windows10 + WSL2
- コンテナ起動環境: Oracle Cloud A1.Flex Instance (ARM64) + 任意の AMD64 PC
まずRustのAPIを起動してみる
とりあえずコンテナのビルド以前に動作確認をしてみないとはじまらないのでやってみる。
本題
無事APIが動いたので、次に本題のDockerfileを書く。
注意: 検索して出てくる内容はちゃんと読もう
Rust Dockerfile と Google検索すると 2番目にScrapBoxのものがヒットしたので最初はそれを参考にコピった。が、これは極限までサイズを小さくする場合に参照する記事であって一般的なやり方ではなかったため、ビルド途中で詰まった。
作成した Dockerfile
一般的なやり方は Rustの公式イメージのREADMEに書いてあった。
なので、それを参考にして 下記のようなマルチステージビルドなDockerfileを書いた
FROM rust:latest as build
COPY . .
# Build
RUN cargo install --config net.git-fetch-with-cli=true --path .
FROM debian:bullseye-slim
# Copy executable
COPY --from=build /usr/local/cargo/bin/schedule /usr/local/bin/schedule
# Run a server
EXPOSE 8100
ENTRYPOINT [ "schedule" ]
今回作るAPIコンテナは ARM64とAMD64の両方で使いたいので 下記のコマンドを使いビルドした。
# Buildxで使うビルド環境作成
docker buildx create --use --name multi-arch-builder --driver-opt network=host --driver-opt image=moby/buildkit:v0.10.6
# (上記ビルド環境を使い) Gitlab container registry にPush
docker buildx build . --platform linux/amd64,linux/arm64 -t registry.gitlab.com/(org)/(repository):latest --push`
無事ビルドが通り、ローカルでコンテナを起動できた。
工夫した点
-
- debian-slimだと 若干コンテナサイズが大きいので よりコンテナサイズが小さい google/distroless を利用した(が動かなかったためもとに戻した)
https://zenn.dev/yoshii0110/articles/21ddb58c6f6bfa
なぜか cargo install の途中で Killed になってしまったため configを足した
https://github.com/rust-lang/cargo/issues/10781#issuecomment-1351670409
RocketのBindIPが 127.0.0.1 になっており APIがリクエストを受け付けてくれなったため0.0.0.0にして頂いた
https://rocket.rs/v0.5-rc/guide/configuration/
Gitlab container registryにPushしたとき manifestがUnknownになってしまうためBuildxをダウングレードした
https://github.com/docker/cli/issues/3969
感想
コンテナ作るだけなら簡単かと思ったら割りと詰まる事が多くて苦戦しました。
この記事が誰かの参考になれば幸いです。