Docker +さびによる第一歩
TL;DR: We are going to install Docker and create five different containers for a Rust program, each one a little more complex than the other.
こんにちは!このポストでは、あなたの錆プログラムをDockerizeする方法をあなたに教えます.私たちは非常に簡単なコンテナから始めて、それからより洗練されたもの(我々がコンパイル時間とイメージサイズの世話をする)に構築します.
私は、あまりにも粒状化の代わりにちょうど最後のものにジャンプすることについて考えました、しかし、私はこれらのポストと簡潔であるよりむしろ明らかであるのを好みます.あなたのためにあまりにも明白で、何があいまいなままであったかについて、私に尋ねて、何でもジャンプするために自由に感じてください.
インストール
まず、Dockerをインストールします.ガイドを取得ガイドをしてMac OS , Linux and Windows .
インストールしたら、このコマンドを実行して実行してテストします.
$ docker run hello-world
それはプルする必要がありますhello-world
からのイメージDocker Hub そして、詳細を説明するテキストブロックを返します.用語集
あなたがDockerに全く新しいならば、私が以下の用語を使うとき、私が意味するものの明確な理解があるのを助けます
Docker:我々は(または、より正確には、私たちのイメージやコンテナに対処するために使用するDockerデーモン)をインストールするアプリケーション;
Dockerfile :ファイル名
Dockerfile
これにはDockerが実行するコマンドが含まれます.錆プロジェクトでは、マニフェストと並んでいるCargo.toml
ファイル;コマンドを実行するとき
build
で指定したすべての画像を作成しますDockerfile
. 画像の結果をコンテナに実行します.例えば、我々Dockerfile
Webサーバーを構築して実行するための指示を持っている場合、イメージはプログラムを含んでいる(すなわち、Webサーバ自体).ベースイメージ:我々が我々のベースに使うイメージです.例えば、私たちのために、錆ベースのイメージ(我々は手動で構築されません、我々はそれを使用する準備ができてダウンロード);
Container画像を実行した結果.コンテナーは、アプリケーションを実行するために必要なすべてを含むコンピュータ上で実行中のプロセスです.より良い理解のためにthis presentation by Liz Rice .
サンプルプロジェクト
私は、使用して構築されたREST APIを使用するつもりですwarp . 自分でビルドしたいなら、チェックしてくださいない場合は、無料でそれをダウンロードしたり、独自のプロジェクトを使用してください;私は、あなたがコマンドを写像する問題がないと思っています.
There are a few differences between the code you'll find in the guide and the one I am using here:
- I am now using IP 0.0.0.0 instead of 127.0.0.1. I changed this so I don't have to tell Docker which IP to bind;
- The old version has two crates: binary (
main.rs
) and library (lib.rs
). That made things harder for Docker (and would make my explanations here too complex) so I just maintained the binary crate and moved the library crate content to a module.
第一
Dockerfile
This and all other files are available . You will identify them by their numbers.
私は非常にシンプルなバージョンから始めて、それを数回改善します.ここでは、私が上記のプロジェクトに取り組んでいます
holodeck
(プロジェクトを使用している場合は変更する必要があります).# 1. This tells docker to use the Rust official image
FROM rust:1.49
# 2. Copy the files in your machine to the Docker image
COPY ./ ./
# Build your program for release
RUN cargo build --release
# Run the binary
CMD ["./target/release/holodeck"]
これにより、以下のコマンドを実行しますDockerfile
そうです.$ docker build -t holodeck .
これはイメージを作成します.それを確認するには、あなたのDockerアプリを見たり、コマンドを使用することがありますdocker images
.$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
holodeck latest aad6ff7c3b4d 47 seconds ago 2.42GB
これを実行するには、次のようにコマンドを発行します.$ docker run -p 8080:3030 --rm --name holodeck1 holodeck
Warp 6, Engage!
パラメータを展開します.-p
ポートをマップするので、Dockerの中の3030(港が我々のワープサーバーが使用している)は8080外で、すなわち、あなたのマシン(あなたがそうしないならば、Dockerはランダムなポートをマップします)を通してアクセス可能です--rm
閉じるこの動画はお気に入りから削除されています--rm
それから実行docker ps -a
すべてのコンテナをリストしてからdocker rm containername
を削除する).localhost:8080
.$ curl --location --request POST 'localhost:8080/holodeck' \
--header 'Content-Type: application/json' \
--header 'Content-Type: text/plain' \
--data-raw '{
"id": 2,
"name": "Bride Of Chaotica!"
}'
Simulation #1 created.
容器を止める$ docker stop holodeck1
holodeck1
あなたが私のようなイメージを走らせるならば、あなたの端末は凍られます.これを避けるために、パラメータを追加することによって-d
:$ docker run -dp 8080:3030 --rm --name holodeck1 holodeck
すごい!これはすばらしい.何度も何度も何度もビルドしなければならない(ということもありますが).なぜこれが問題なのか.コンパイル時間.毎回走るdocker build
, 錆は、すべての建物のプロセス再びすべての;そして、我々がリリースのために建設している事実は、それをより悪くします.それを直しましょう.
二番目
Dockerfile
これはより具体的な選択肢です.# Rust as the base image
FROM rust:1.49
# 1. Create a new empty shell project
RUN USER=root cargo new --bin holodeck
WORKDIR /holodeck
# 2. Copy our manifests
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml
# 3. Build only the dependencies to cache them
RUN cargo build --release
RUN rm src/*.rs
# 4. Now that the dependency is built, copy your source code
COPY ./src ./src
# 5. Build for release.
RUN rm ./target/release/deps/holodeck*
RUN cargo install --path .
CMD ["holodeck"]
I am using
install
, but this is the same asbuild
, except that it places the binary on the indicated path, in this case, theWORKDIR
.
このようにしてコンパイラaeonを回避します.新しいプログラムに接続された依存性だけを構築することによって
Dockerfile
, 我々のプログラム(コマンド4と5)を構築してください、我々はキャッシュを無視してDockerを止めます.なぜそれは機能しますか?何故なら私たちのすべての命令だからですDockerfile
新規作成layer , これは画像の変更です.我々が走るときdocker build
, 修正された層だけが更新され、残りはローカルキャッシュから取得されます.実際には、マニフェストを変更しない限り、依存関係を再構築する必要はありません.私のケースでは、323.6秒を取った最初のビルドの後、2番目の1つ(私はちょうど変更しました)
main.rs
) のみ33.9秒かかりました.すごい!しかし...別の問題があります:イメージサイズ.たとえば、私のものは1.65 GBを持ちました.Let's put a little fixin' on it .
第三
Dockerfile
Isaacのポストを訪れたら、2つのベースイメージを使って「連鎖する」ビルドでこれを管理しているのがわかるでしょう.彼は最初から何でもしたFROM rust
, これは、すべてが構築され、別のと呼ばれるビルドですFROM rust
, 最初のビルドから必要なファイルだけをコピーします.これは最終的なイメージがこれらの最後のコピーされたファイルだけを保持するのを許します、したがって、イメージサイズを減らします.このようにします.
FROM rust:1.49 as build
# create a new empty shell project
RUN USER=root cargo new --bin holodeck
WORKDIR /holodeck
# copy over your manifests
COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml
# this build step will cache your dependencies
RUN cargo build --release
RUN rm src/*.rs
# copy your source tree
COPY ./src ./src
# build for release
RUN rm ./target/release/deps/holodeck*
RUN cargo build --release
# our final base
FROM rust:1.49
# copy the build artifact from the build stage
COPY --from=build /holodeck/target/release/holodeck .
# set the startup command to run your binary
CMD ["./holodeck"]
それは、1.66 GBから1.26 GBまでイメージサイズを減らしました.しかし、私はDockerfile
, それで、あなたは我々がよりよくすることができるということをすでに知っています.第四
Dockerfile
我々が今することは、我々が使っているさび画像タグを変えることです.タグは「イメージ変種」、すなわち特定の目標を満たすように設計された代替画像を言う別の方法です.それで、我々がスペースを節約しているイメージが欲しいならば.it is a tag that we're looking for .そして、すべてはちょうど2番目を取り替えることを意味します
FROM
でFROM rust:1.49-slim-buster
このイメージタグは、Debianのタグに組み込まれた錆を使用しますbuster slim よりコンパクトなイメージを作成するには.現在、1.26 GBの代わりに、642.3 MBを持ちます.Some people might wonder why I didn't use Alpine. Well, I did, and buster-slim was 10MB smaller. But the real reason why I avoided Alpine will be clear in the next step.
5番目の
Dockerfile
私は、最小限のイメージサイズのためのこの狩りが常に必要であると思いません;あなたは理由がある.私が理由(あなたにそれを示す)を持っているように、私は本当に小さいDockerイメージを与える1つの最終的な変化をします.このためには、実行されるバイナリだけの錆がないイメージを必要とします(これは結局コンパイルされた言語の美しさの一つです).
そのようなことを達成するために、我々はバイナリベースを構築するために錆びベースのイメージを使用して、ちょうどバイナリをLinuxイメージにさびないで動かします.そして、それを行うには、我々は使用されますdebian:buster-slim 自身.
Again, regarding Alpine. I didn't use it here either for two reasons:
- To run a Rust code in Alpine it has to be compiled with MUSL, which adds an extra layer of complexity to this beginner-intended post;
- I am not sure that MUSL is a good option.
結果:75.39 MB.それは2.42 GBから長い道のりです.
全体的な比較をしましょう.
それだ!今までのところ、ありがとうございました.バイ!
カバーイメージAron Yigin
Reference
この問題について(Docker +さびによる第一歩), 我々は、より多くの情報をここで見つけました https://dev.to/rogertorres/first-steps-with-docker-rust-30oiテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol