🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

2回答

2819閲覧

Dockerfileの書き方 RUNでシェルを走らせるか、COPYしたsetup.shを動かすのか、メリット・デメリットを知りたい。

Kchan_01

総合スコア110

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

1クリップ

投稿2021/03/18 06:25

編集2021/03/18 11:55

Dockerを学び始めた初心者です。

Dockerfileでいろいろインストールするときに、DockerfileにRUNコマンドを書いて、インストールしたり、設定したりとするのがよいのか、予め実行させる処理をシェルスクリプトにまとめ、ファイルとしてCOPYコマンドでtmpなどに入れて実行させるのか、どちらが良いのでしょうか。

私としては、Dockerのコンテナはできる限り何もない状態にしておき、runするときにシェルを動かして、imageを使い回せるような形にするのが正解かと思っていたのですが、けっこうDockerfile内のRUNで設定している人も多いようで、どちらが最適なのかわかりません。

結局は、imageを使い回すような処理は書くことはなさそうだとも感じています。

良い点、悪い点など教えていただけますと幸いです。

よろしくおねがいします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

回答のコメント欄で私の勘違いがわかったのでそちらをまとめます。

ENTRYPOINTや、CMDの処理がdocker startするたびに実行されてしまうということが理解できていませんでした。全部シェルスクリプトに書いていました。

試したところ、シェルで実行させていた処理は、毎回コンテナを立ち上げるたびに初期化されていました。

@matsuandさん
RUNはイメージビルド時に実行されるコマンド、CMDはコンテナ内にてイメージが実行される際に実行されるコマンド。利用目的が異なると思います。コンテナを再起動したときのことを考えると違いが明らかで、(変更点がなければキャッシュが効くので)再実行されなくてよいコマンドが RUN、(再)実行されて欲しいコマンドが CMD ではないですか?(CMDはイメージビルド時には実行されません。)

  • 再実行されなくてよいコマンドが RUN
  • (再)実行されて欲しいコマンドが CMD(CMDはイメージビルド時には実行されません。) もしくはENTRYPOINT。

シェルスクリプトにしかかけないことをシェルスクリプトに書くべきで、それ以外はDockerfileに書くべきと結論づけました。

投稿2021/03/18 14:53

Kchan_01

総合スコア110

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Dockerfileはdocker-composeとセットで使う事がほとんどだと思うけど、Dockerfile内では.envやdocker-compose.ymlで設定した引数を利用出来るのでRUNの一部として利用出来ます
動的に変数を作り、それをRUNに使う事も出来ます

対して予め用意したシェルスクリプトだとそれが出来ません
※シェルの中で環境変数・変数を作って使う事は出来ます
RUNでsedして書き換える事も出来ます

どちらが最適なのかわかりません。

自分のやり易いようにどうぞ
個人利用の範囲ならやり易い方法や好みの方法から始めて不都合があれば適宜手法を変えてけばいいです
ただし他の人にイメージを配布するならシェルスクリプトをエントリーポイントとしてイメージに突っ込むしかないでしょう

投稿2021/03/18 07:01

hentaiman

総合スコア6426

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

matsuand

2021/03/18 08:10

RUNはイメージビルド時に実行されるコマンド、CMDはコンテナ内にてイメージが実行される際に実行されるコマンド。利用目的が異なると思います。コンテナを再起動したときのことを考えると違いが明らかで、(変更点がなければキャッシュが効くので)再実行されなくてよいコマンドが RUN、(再)実行されて欲しいコマンドが CMD ではないですか?(CMDはイメージビルド時には実行されません。)
hentaiman

2021/03/18 08:21

> ただし他の人にイメージを配布するならシェルスクリプトをエントリーポイントとしてイメージに突っ込むしかないでしょう これと違いますかね?
hentaiman

2021/03/18 08:39

> 結局は、imageを使い回すような処理は書くことはなさそうだとも感じています。 との事ですが、matsuandさんはどちらが最適だと思いますか?自分なら自分の回答を見てRUNを選んでくれればいいんじゃないと思って回答してます。 ※質問見直したけどCMDの話は特に無いのでどこに絡めれば良いのか分かりませんが・・・
matsuand

2021/03/18 09:11

「エントリーポイント」と表現されていたので CMDとの対比と解釈してコメントしていましたが、そうではないんですかね(?) そういう対比でないのであれば hentaiman 様の仰るとおり「お好みで」というのが回答かと思います。ただ事細かく突っ込むと、RUN でできることをシェルにするのは、単に書く場所を変えただけのように映るので、細かな点で融通が利く利かないはあるのかもしれませんが、可読性や保守を考慮したら、そんなまわりくどくしなくて良いという印象を抱きます。
hentaiman

2021/03/18 10:26

イメージを配布するならRUNで細々書くのは無理なのでエントリーポイントが必要、そのエントリーポイントとしてシェルスクリプトを用意するという回答と書いたつもりでしたが、対比になるんですかね? > RUN でできることをシェルにするのは イメージを配布するのにRUNで出来るんですかね?上のコメントの通り出来ないと思ってエントリーポイントとしてのシェルスクリプトと書いたんですが、間違ってたら教えてください
hentaiman

2021/03/18 10:42

それは自分に対してのコメントですか?だとしたら言いたい事が分からず申し訳ないですが、自分の回答はイメージにするならDockerfileにRUN書いてみたいな考え方は出来ないからシェルスクリプトに書かないとねって話です
Kchan_01

2021/03/18 10:43 編集

@matsuandさん ENTRYPOINTや、CMDの処理がdocker startするたびに実行されてしまうということが理解できていませんでした。全部シェルスクリプトに書いていました。 試したところ、シェルで実行させていた処理は、毎回コンテナを立ち上げるたびに初期化されていました。 > RUNはイメージビルド時に実行されるコマンド、CMDはコンテナ内にてイメージが実行される際に実行されるコマンド。利用目的が異なると思います。コンテナを再起動したときのことを考えると違いが明らかで、(変更点がなければキャッシュが効くので)再実行されなくてよいコマンドが RUN、(再)実行されて欲しいコマンドが CMD ではないですか?(CMDはイメージビルド時には実行されません。) - 再実行されなくてよいコマンドが RUN - (再)実行されて欲しいコマンドが CMD(CMDはイメージビルド時には実行されません。) もしくはENTRYPOINT。 ということですね。
68user

2021/03/18 10:59

$ cat Dockerfile FROM ubuntu:18.04 RUN apt-get update && apt-get -y install python3.7 && ... CMD bash と、 $ cat Dockerfile FROM ubuntu:18.04 COPY setup /setup RUN /setup/setup.sh CMD bash $ cat setup/setup.sh #!/bin/sh apt-get update && apt-get -y install python3.7 && ... のどっちがいいんですか、という話ではない? (えっ、もしかして違うの?)
68user

2021/03/18 11:02

ああ、「runするときにシェルを動かして」ってのは RUN じゃなくて docker run ってことですかね。 もしそうなら、はい、理解しました。
hentaiman

2021/03/18 11:04

そうでした、書かれたコメントに流されてそこ忘れてましたすいません そして > 自分のやり易いようにどうぞ で終わってますね 失礼しました
matsuand

2021/03/18 11:06

@Kchan_01 さん 再実行されるされないを目指すという表現は適切でなかったかもしれません。そのことをご理解ください。要はサーバー環境(サーバーイメージ)を作るのに必要なことはすべて RUN に書くべきものと思います。シェルとして外だしにするかどうかは、ビルドキャッシュとしてどのように効くかという問題をはらむため、そこらあたりがわかっていないと、「どちらでもお好きなように」という回答は実は適切ではない、と後々思うようになりました。
hentaiman

2021/03/18 11:30

キャッシュが邪魔なら--no-cacheって軽い感じでやってましたけど、キャッシュって重要視しなきゃいけないものですか?dockerに限らずキャッシュは邪魔なら消すっていう扱いしてるんですけど、dockerの場合違うんですか? 普通に分からないので教えてください
matsuand

2021/03/18 12:15 編集

@hentaiman さん、 ご質問なら新たに挙げて頂くのが良いかと思いますので、当コメントによりこのスレでの最後とさせて頂きたく思います。キャッシュを利用するのが当たり前と捉えていましたので、適切に説明できるかわかりませんが試みてみます。マルチステージビルドにて共通ベースイメージを利用する場合、キャッシュを利用してビルド時間短縮が図られる例があります。またCI(継続的インテグレーション)に適していると言われます。環境変更や依存パッケージの更新などにおいてレイヤーキャッシュのうち必要なものだけが再ビルドされます。これもキャッシュがあれば再ビルドの所要総時間を減らすと考えられます。
hentaiman

2021/03/18 13:15

> マルチステージビルドにて共通ベースイメージ なるほど!確かに! > ご質問なら新たに挙げて頂くのが良いか 回答に対するツッコミだったので、誤っている点を正確に知りたくて聞いただけなので、特に新たに質問して訊きたい事ではありません。 ですので、コメントではなく回答をされていれば特に質問はしなかったです。 今回はキャッシュを活かすパターンが聞けて良かったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問