Docker超入門:UbuntuとNginxを題材にDockerfileの書き方を学ぼう

 Dockerを学ぶうえで避けて通れないのが Dockerfile です。Dockerfileはコンテナを構築するためのレシピのようなもので、書かれた命令に従ってイメージが作成されます。ここでは、UbuntuとNginxを題材にDockerfileの書き方を学びながら、各命令の役割を丁寧に解説していきます。

今回のDockerfile

 まずは、サンプルのDockerfileを確認してみましょう。このサンプルは「UbuntuとNginxでWebサーバーをビルドする①」で作成したDockerfileの記述内容です。

# Step1 : Ubuntuイメージの作成
FROM ubuntu:latest

# Step2 : Nginxのインストール
RUN apt-get update && apt-get install -y -q nginx

# Step3 : htmlファイルのコピー
COPY index.html /var/www/html

# Step4 ... 80番ポートの公開
EXPOSE 80

# Step5 : コマンドの実行(Nginxの開始)
CMD ["nginx","-g","daemon off;"]

 このDockerfileを使えば、Ubuntuベースの環境にNginxをインストールし、ローカルの index.html を配置してWebサーバーとして起動できます。

Step1:ベースイメージの指定(FROM)

最初にベースとなるイメージを指定します。

書式

FROM <イメージ名>:<タグ>
項目説明
イメージ名使用するベースイメージ名
タグバージョンやリビジョン、省略時は latest

実行例

FROM ubuntu:latest

 ここでは最新のUbuntuをベースにしています。つまり、このイメージの上にNginxを追加してカスタマイズしていくわけです。

Step2:Nginxのインストール(RUN)

次にNginxをインストールします。

書式

RUN <コマンド>

RUN命令には Shell形式Exec形式 の2つの書き方があります。

書式説明使用例
Shell形式文字列をシェル経由で実行。/bin/sh -c が自動的に呼び出されるRUN apt-get install -y nginx
Exec形式配列形式で直接実行。余計なシェルを介さないため安全性が高いRUN ["apt-get","install","-y","nginx"]

Exec形式が推奨される理由

  • シグナル伝達が正しく行われる
    Shell形式ではコマンドがシェルの子プロセスとして動作するため、コンテナの終了シグナルがアプリケーションに正しく届かない場合があります。Exec形式ならプロセスが直接PID1として実行されるため、シグナルハンドリングが正しく機能します。
  • 予期しないシェル展開を避けられる
    Shell形式では *$VAR などのシェル展開が意図せず動作してしまう可能性があります。Exec形式は配列で正確に指定するため、コマンド解釈がブレません。
  • 移植性と可読性が高い
    Shellに依存しないため、異なる環境でも一貫して動作します。特にCMDやENTRYPOINTでの使用はExec形式がベストプラクティスとされています。

Step3:ファイルのコピー(COPY)

ローカルの index.html をコンテナにコピーします。

書式

COPY <ホスト側パス> <コンテナ内パス>

実行例

COPY index.html /var/www/html

 これにより、Nginxのドキュメントルート /var/www/htmlindex.html が配置され、ブラウザからアクセスできるようになります。

Step4:ポートの公開(EXPOSE)

 NginxはHTTPのデフォルトポート 80 を使います。そのためDockerfileでポートを公開します。

書式

EXPOSE <ポート番号>

実行例

EXPOSE 80

 この命令は「コンテナがこのポートを利用します」という宣言です。実際に外部からアクセスできるようにするには、docker run -p 80:80 のようにポートをマッピングする必要があります。

Step5:コンテナ起動時のコマンド(CMD)

最後にコンテナ起動時に実行するコマンドを指定します。

書式

CMD ["実行ファイル","引数1","引数2"]
CMD <文字列>

CMDもRUNと同じく、Shell形式Exec形式 の2種類があります。

書式説明使用例
Exec形式配列で指定、シグナル伝達や可搬性に優れる。CMD ["nginx","-g","daemon off;"]
Shell形式/bin/sh -c を経由して実行CMD nginx -g 'daemon off;'

 CMDの場合もExec形式の方が推奨されます。特にNginxのようなサーバープロセスをフォアグラウンドで動かす場合、正しくSIGTERMなどの終了シグナルを受け取るためにExec形式が必須です。

パッケージ管理システム(APTの役割)

 RUN命令で使った apt-get は、Ubuntuが採用している APT(Advanced Packaging Tool) というパッケージ管理システムのコマンドです。

コマンド説明
apt-get updateパッケージ情報を更新
apt-get install <パッケージ名>パッケージをインストール
apt-get upgrade既存パッケージをアップデート

これにより、Nginxを含む必要なソフトウェアを自動で解決しながら導入できます。

まとめ

 今回のDockerfileはとてもシンプルですが、FROM → RUN → COPY → EXPOSE → CMD というDockerfileの基本的な流れがしっかり詰まっています。
 これを理解することで、他のアプリケーションを組み込むDockerfileも書けるようになり、コンテナ環境を自在に構築できるようになります。