Edited at

Dockerfileの書き方を深掘りしつつまとめてみた


はじめに

この記事は、現在Dockerについて学習している自分が、Dockerfileの書き方について、

ファイル内に記述されているコマンドの意味などをアウトプットを兼ねて解説した内容になります。


過去に投稿したDocker関連の記事はこちら


第1回Dockerハンズオン初心者・中級者編で学んだことをまとめてみた

https://qiita.com/yuta-ushijima/items/fdcaea4220e773a5ad2d


docker-compose.ymlの書き方について解説してみた

https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04


Dockerfileってなに?

Dockerを使ってアプリケーションを動かす際に、DockerImage(以下Image)の元となるファイルのこと。食べ物でいえば、原材料のようなものと思うとわかりやすいかもしれません。

Dockerfile内には、Imageを生成する際に実行させたいコマンドを、命令を実行するための環境変数の引数にして記述します。


Dockerfileサンプルコード


# 使用するrubyのバージョン
# rubyの2.4.1というImageをベースにDockerfileを作成する
FROM ruby:2.4.1

# このDockerfileのメタデータを記述
# MAINTAINERはdeprecateになった
LABEL maintainer="Yuta_Ushijima <contact@yuta-u.com>"|

# 文字コードの設定
# 日本語を受け付けるように設定(rails consoleで日本語を使うなど) => LANG=C.UTF-8
# 設定したロケールの値をC.UTF-8で上書きする => LC_ALL=C.UTF-8
# 文字コードのカテゴリをutf-8に設定 => LC_CTYPE="utf-8"
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
LC_CTYPE="utf-8"

# 使用するエディタ
ENV EDITOR vim

# インストールするライブラリなどをshell形式で記述。\(バックスラッシュ)を使って、一つのRUNで複数のコマンドを実行できる。
RUN apt-get update --fix-missing \
&& apt-get -y upgrade \
&& apt-get install -qq -y \
apt-utils \
build-essential \
ca-certificates \
curl \
git \
glances \
graphviz \
htop \
libcurl3 \
libpq-dev \
man \
mysql-client \
nano \
nodejs \
patch \
software-properties-common \
sudo \
unzip \
vim \
wget \
xvfb \
zlib1g \
zlib1g-dev \
&& apt-get autoremove -y \ => 不要なパッケージの自動削除。-yで確認ダイアログの非表示。
&& apt-get clean \ => パッケージキャッシュの削除
&& fc-cache -f -v => 利用可能なフォントのキャッシュを更新。

# bundle installをスムーズに実行させるため、予め重めのgemをここでinstallしていおく
RUN gem update --system
RUN gem install -q --no-rdoc --no-ri pkg-config --version 1.3.1
RUN gem install -q --no-rdoc --no-ri rails --version 5.2.1
RUN gem install -q --no-rdoc --no-ri nokogiri --version 1.8.4
RUN gem install -q --no-rdoc --no-ri mysql2 --version 0.5.2

# GemfiletとGemfile.lockをルートディレクトリにコピー
COPY Gemfile Gemfile.lock ./
# Gemfile.lockが通常のファイルであれば、bundle installを実行
RUN if test -f Gemfile.lock; then \
bundle install --binstubs --jobs=4 --retry=3; \
fi
# コピー元のGemfileとGemfile.lockを削除
RUN rm Gemfile Gemfile.lock

# ディレクトリの作成
RUN mkdir -p /memo-app/backend

# 実行するディレクトリの指定
WORKDIR /memo-app/backend

# 現在のディレクトリ(ここでは/memo-app/backend)の新規ファイルやディレクトリをルートディレクトリに追加
ADD . .

# RAILS_SERVE_STATIC_FILES=trueにすることで、rails serverを起動時にpublic/assetsを読み込む
ENV RAILS_SERVE_STATIC_FILES=true \
PORT=3000 \
# コンテナにxtermというターミナルエミュレータを割り当てる
TERM=xterm

ENV PORT=3000 \
# RACK_ENV=development \
# RAILS_ENV=development \
RAILS_SERVE_STATIC_FILES=true \
TERM=xterm

EXPOSE 3000
EXPOSE 3310


Dockerfileで記述する環境変数について

環境変数の種類自体は、そこまで数が多くないので、それぞれを表にしてまとめてみます。

項目
意味
リファレンスリンク

FROM
ビルドする際にどのImageをベースにするか
http://docs.docker.jp/v1.10/engine/reference/builder.html

LABEL
Dockerfileのメタデータを記述
https://docs.docker.com/engine/reference/builder/#label

ENV
環境変数のkeyとvalueを設定
https://docs.docker.com/engine/reference/builder/#env

RUN
引数に設定したコマンドをビルド時に実行。引数の書き方がshell形式とexec形式がある。
https://docs.docker.com/engine/reference/builder/#run

COPY
プロジェクトソースにあるファイルやディレクトリを指定先にコピーする
http://docs.docker.jp/v1.10/engine/reference/builder.html#copy

WORKDIR
RUNやCMDなどの命令を実行するディレクトリを指定
http://docs.docker.jp/v1.10/engine/reference/builder.html#workdir

ADD
新しく追加されたファイルやディレクトリを指定先に追加
http://docs.docker.jp/v1.10/engine/reference/builder.html#add

EXPOSE
コンテナ実行時に指定したポートで接続用意ができていることをDockerに伝える
https://docs.docker.com/engine/reference/builder/#expose


RUNにおけるapt-getコマンドについて

Dockerfileのベストプラクティスの要点をまとめると、



  • apt-getupdateinstallは同一のRUNで実行すること

# -yで確認ダイアログを出さずにinstallを実行する

apt-get update && apt-get install -y \


  • RUNの最終行でapt-get cleanしてキャッシュを削除すること
    (apt-get clean allじゃなくてもapt-get cleanだけでOK。apt-get cleanのあとにどんな引数を書いても無視されるため)

RUN apt-get update && apt-get install -y \

aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
lxc=1.0* \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& apt-get clean \


  • 更新しやすくするために、installするライブラリはABCの降順で記述すること


参考サイト


Cロケールについて

https://docs.oracle.com/cd/E26924_01/html/E27144/glmbx.html

https://wiki.archlinux.jp/index.php/%E3%83%AD%E3%82%B1%E3%83%BC%E3%83%AB


Dockerfileのベストプラクティス

http://docs.docker.jp/engine/articles/dockerfile_best-practice.html


apt-getコマンドについて

https://qiita.com/white_aspara25/items/723ae4ebf0bfefe2115c


apt-get clean allについて

https://askubuntu.com/questions/144222/how-do-apt-get-clean-and-apt-get-clean-all-differ


fc-cache -fvについて

https://qiita.com/nju33/items/b80d92a4257edeb4b9a1


シェルスクリプトのif文について

https://shellscript.sunone.me/if_and_test.html


xtermについて

http://docs.docker.jp/v1.12/engine/reference/run.html#id67