LoginSignup
1
1

More than 1 year has passed since last update.

【Docker】Dockerfileを記載するために用いるコマンド

Last updated at Posted at 2023-02-14

はじめに

Railsなどを中心に勉強中のエンジニア初心者が他の記事を参考にしたり、実際に実装してみたりして、アウトプットの一環としてまとめたものです。
間違っていることもあると思われるので、その際は指摘いただけると幸いです。

Dockerfileとは

docker imageの設計図(Dockerfileからdocker imageを作成する)。

他の人がDockerfileを見たときに、どのようなコンテナが生成されるか一目瞭然となる

Instruction argumentsの形で記載していく。

Instructiondockerに命令を送るコマンドで基本的には大文字で記述する(小文字でも動く)、argumentsは引数

Instruction:FROM

Dockerfileの一番最初に記述する。

ベースとなるimageを指定している。ここで指定したimageの上に各Layerが追加されていく。

基本的にはOS(ubuntualpineを選択する事が多い)を指定することになる。他の人が作成したimageを指定することも可能。

ubuntuは約70MBあるが、alpineは5MBと軽量なのが特徴。必要最低限の機能を備えたimageを取得する事が大切。

# Dockerfile
FROM ubuntu:latest

Instruction:RUN

右側にある文字列をLinuxコマンドとして実行する。

RUNを使うことでコンテナを独自にカスタマイズする事ができる。

RUN毎にimage layerが重なっていく。RUNを何度も実行してしまうと、docker imageの容量が大きくなってしまうため注意が必要。

# Dockerfile
FROM ubuntu:latest
RUN touch test

docker imageLayer

Dockerfileのベストプラクティスとしては、docker imageLayer数を最小限にする事が求められる(docker imageを小さくするため)。

Layerを作るのはRUNCOPYADDの3つのコマンドで、これらのコマンドを使うときは注意する。

コマンドを&&で繋げて1回のRUNで実行できるようにする(「 \ 」バックスラッシュで改行できる)

-yオプションはパッケージをインストールする際のインタラクティブな質問にYESで答えることを意味する。

# Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
		xxx \
		yyy \
		zzz

		# インストールするパッケージはアルファベット順に並べると良い

ubuntuでパッケージをインストールするにはapt-getコマンド(またはaptコマンド)を使う

$ apt-get update # 新しいパッケージリストを取得

$ apt-get install <package1> <package2> <package3> # <package>をインストール。半角スペースを空けてパッケージ名をつなげることで1回のapt-get installで実行可能

docker imagecache

Dockerfileからdocker imagebuildする時は、Layer毎のcacheを用いる事ができる。

そのため、Dockerfile構成を検討する際はインストールする事が確定したパッケージのRUNコマンドに新しいパッケージを追加して実行するのではなく、別のRUNコマンドとして実行すると良い。

既に実行されているRUNコマンドのLayerに関しては、cacheを利用する事ができるためである。

Dockerfileが完成した後に、まとめられるコマンドをまとめていくと良い(必ずまとめる)。

# Dockerfile

FROM ubuntu:latest
RUN apt-get update && apt-get install  -y \
		aaa \
		xxx \
		yyy \
		zzz

# 確定したxxx,yyy,zzzのRUNコマンド内に新しくaaaを追加してしまうと、
# 既にあるxxx,yyy,zzzのLayerは無視され、新しいLayerが構築されてしまう

Instruction:CMD

コンテナのデフォルトのコマンドを指定する。コンテナを起動したときに最初に実行されるコマンドとなる。

CMD[””executable, “”param1, “param2”]という構文をとり、原則Dockerfileの最後に記述する。

実行したいコマンドがない場合は”/bin/bash”とするのが一般的。

CMDがないとFORMで取得してきているimageのデフォルトコマンドが実行されるが、何が実行されるか不明なため、CMDで実行コマンドを記述するようにした方がわかりやすい。

FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    curl \
    cvs \
    nginx
CMD ["/bin/bash"]

RUNCMDについて

RUNLayerを作るが、CMDLayerを作らないという違いがポイントとなる。

docker imageLayerに持っておきたい場合はRUNで記載する。

build contextおよびdocker deamonについて

docker buildを実行する際は、Dockerfileを指定するのではなく、Dockerfileが存在しているディレクトリ(「.」カレントディレクトリ)を指定する。

docker buildを実行すると、指定されたディレクトリがdocker deamonに渡され、docker deamonが渡されたディレクトリとそのディレクトリ内のDockerfileを基にdocker imageを作る。

このディレクトリのことをbuilde contextという(build時にbuild context内のファイルを活用する事ができる)。

docker context内には不要なファイルなどは配置しないようにする事が望ましい。

docker buildを実行するクライアント側と、docker deamonが存在するDockerホスト側が同一PC内であれば、build contextの容量が大きくとも通信時間はあまりかからないが、同一PC内に存在しない場合はREST APIで通信するため時間がかかってしまう恐れがある。

builde context内のファイルをdocker imageに反映させるためには、ADDCOPYというINSTRUCTIONが必要になる(Image Layerとして反映される)。

Instruction:COPY

build context内のDockerfile以外のファイル(またはディレクトリ)をdocker imageに組み込んで、最終的にはコンテナで使う事ができる。

# Dockerfile
FROM ubuntu:latest
RUN mkdir /new_dir
COPY something /new_dir

# COPY <src> <dest>

Instruction:ADD

tarの圧縮ファイルを解凍したい場合はADDを使用する。tarファイルをdocker imageに渡した際に自動で解凍まで実行してくれる。

ファイル容量(フォルダ容量)が大きいファイルをdocker imageに送る場合は、圧縮してから送信することになるため、ADDを使用するとよい。

# Dockerfile
FROM ubuntu:latest
ADD compressed.tar /

# ADD <src> <dest>

Dockerfileという名のファイルがbuild contextに存在しない場合

Dockerfileを開発用(Dockerfile.dev)とテスト用(Dockerfile.test)など複数用意しておく場合がある。

そのような場合は下記のようなコマンドで実行する。

$ docker build -f <Dockerfile_name> <build context>

Instruction:ENTRYPOINT

ENTRYPOINTを使用してデフォルトで実行するコマンドを定義することができる。

特徴としては、docker run時に別のコマンドを実行させる事ができなくなる(コマンドの上書きが不可能)。

また、ENTRYPOINTを使用した場合は、CMDはオプションを定義する役割となる。

dockerのコンテナをコマンドのように扱いたい場合はENTRYPOINTを使用する事がある。

# Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    curl \
    cvs \
    nginx
CMD ["ls", "--help"]

# デフォルトでlsコマンドを実行し、さらに--helpをオプションとして付けている

$ docker run <image> pwd

# デフォルトで実行するコマンドがCMDで定義されている場合は、実行するコマンドの上書きが可能
# Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y \
    curl \
    cvs \
    nginx
ENTRYPOINT ["ls"]
CMD ["--help"]

# デフォルトでlsコマンドを実行するように定義している(コマンドの上書きは不可能)
# CMDで--helpをオプションとして指定している

$ docker run <image> pwd

# デフォルトで実行するコマンドがENTRYPOINTで定義されている場合は、実行するコマンドの上書きが不可能(エラーになる)

$ docker run <image> -la

# オプションに関しては、上書きが可能

Instruction:ENV

Dockerfileで環境変数を設定する際に使用する(環境変数:OSの上で動くあらゆるプロセスが情報を共有するための変数)。

# Dockerfile
FROM ubuntu:latest
ENV key1 value
ENV key2=value
ENV key3="v a l u e" key4= v\ a\ l\ u\ e
ENV key5 v a l u e

Instruction:WORKDIR

Docker Instructionを実行するディレクトリを変更する際に使用する。

WORKDIR <絶対path>というように記述する。

WORKDIRで指定したディレクトリが存在しない場合は、そのディレクトリが自動で作成されるため、mkdirなどでディレクトリを作成する必要はない。

# Dockerfile
FROM ubuntu:latest
RUN mkdir sample_folder
RUN cd sample_folder
RUN touch sample_file

# RUNコマンドは基本的にはルート直下で実行されるため、上記のようにcdコマンドでsample_folderに移動しても、「touch sample_file」はルート直下で実行される
# Dockerfile
FROM ubuntu:latest
RUN mkdir sample_folder && \
		cd sample_folder && \
		touch sample_file

# 上記のように&&でコマンドを繋げた場合は、「touch sample_file」は「sample_folder」配下に作られる。
# Dockerfile
FROM ubuntu:latest
WORKDIR /sample_folder
RUN touch sample_file

# 上記の状態でコンテナに入ると。「sample_folder」にいることになる(WORKDIRで「sample_folder」を指定して以降、戻るコマンドを実行していないため)

最後に

いかがでしたでしょうか。
今回はDockerfileを記載するためのコマンドについてまとめてみました。
ここ違うよ!でしたり、こうした方がいいよ!などがあればコメントいただけると幸いです。

他にも下記のような記事を投稿しております。
興味がありましたら、ぜひご覧ください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1