Dockerfileからオリジナルnginxのイメージを作る方法

前回は、サボる方法(Docker Hubから公式イメージを持ってきてそれを使う方法)を紹介しました。

Docker Hubから取得したイメージを利用するのも良いのですが、だんだんカスタマイズしたくなってきます。

そんな、「もう少しこうしたい」と感じるようになったあなたのために、

今回のテーマは「自分でDockerfileからイメージを作ってみる」です。

ということで、今回は、

  1. Dockerfile作成
  2. 関連ファイルの作成
  3. イメージの作成(ビルド)
  4. イメージからコンテナを起動
  5. 動作確認

という手順で、例にならって、お馴染みnginxさんです。

Ubuntuにnginxを入れて「Welcome to nginx!」じゃないnginxを作ります。

スポンサーリンク

今回覚えれるコマンド

カレントディレクトリのDockerfileをビルドする

% docker build -t ${REPO}:${TAG} .

ポートを指定してコンテナを起動する

% docker run -itd -p ${LOCAL_PORT}:${COTAINER_PORT} ${REPO}:${TAG}
スポンサーリンク

できるもの

http://localhostにアクセスすると、これが表示されるものを作ります。

デフォルトでは、以下のような画面になります。

ただ、nginxの部分変えただけじゃんという感想を抱くかもしれませんが、はいそうです笑

解説を含めた事前準備

前提条件

nginx_dir」というディレクトリにDockerfile、index.htmlというファイルを用意します。

Dockerfileをビルドする時はこのファイルがある前提でビルドします。

nginx_dir
 L Dockerfile
 L index.html

それでは、上記2つのファイルを作成していきます。

Dockerfileの作成

まずは、Dockerfileです。全然怖くありません。以下のようにやりたいことを淡々と書いていきます。

FROM ubuntu:20.04

RUN apt-get update
RUN apt-get install -y nginx

COPY ./index.html /var/www/html

EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]

コマンドを順番に説明していきます。

1行目:FROM

FROMコマンドは「なんのイメージをベースを使いますか?そのイメージのバージョンは何ですか?」を記載してあげます。

これをベースイメージと言います。

今回は、Ubuntuの20.04のバージョンを使うぜという意味で「ubuntu:20.04」宣言しています。

これ前回のDocker Hubからイメージ取得する回でも記載した{REPO}:{TAG}の部分に相当します。

% docker pull ${REPO}:${TAG}

要は、内部でdocker pullをしている感じです。

他のベースイメージを利用したければこの部分を変更すれば良いわけです。

例えば、Dockerで使うOSのデファクトスタンダードでもあるAlpine Linuxをベースイメージにしたい場合は、alpine:3.15.3と記載すれば良いわけです。

さらに、バージョン({TAG})もとりあえず最新版を持ってきてくれればいいというめんどくさがり屋さんは、xxxx:latestと記載すればそのイメージの最新版を引っ張ってきてくれます。

※以下実施していくものはUbuntuベースで作ってます。Alpineベースでは動かない部分もありますので気をつけてください。

3, 4行目:RUN

RUNコマンドは「命令することがされた状態のイメージを作ってね」というコマンドになります。

今回はRUNコマンドが2つありますが、「apt-get update」と「apt-get install -y nginx」を実行された状態のイメージを作ってねという意味になります。

ここがオリジナルイメージを作る際にオリジナル要素を出せる部分です。

例えば、RUN mkdir xxx_dirとすれば、xxx_dirが作られた状態でイメージが作成されます。

6行目:COPY

COPYコマンドは「現実世界のファイルをコンテナ世界にコピーする」というコマンドになります。

今回はnginxの設定ファイルを一部置き換える目的で、ローカルにあるindex.htmlファイルをコンテナ世界の/var/www/htmlにコピーしてねという意味になります。

なお、圧縮された状態のものを展開しつつ指定した場所へコピーするというADDというコマンドもありますが、これの使い分けや違いなどは各自調べてみてください。

参考:ADDとCOPY

8行目:EXPOSE

EXPOSEコマンドは「コンテナ世界としてはこのポートを開けて待ってます」というコマンドになります。

今回は80ポートをリッスンポートとして指定してます。

ただ、上記の通り「コンテナ世界”としては“」なのがポイントでもあるので注意してください(後述)。

ENTRYPOINT

ENTRYPOINTコマンドは「コンテナを起動したときにこれ実行した状態にして」というコマンドになります。

今回はnginxのプロセスを立ち上げた状態にしてという命令をしてます。

また、使い分け方が今いいちわからなくてもなんとなく動いちゃう可能性が高いCMDという似ているコマンドがありますが、「CMDは引数のために使うべき」と公式には記載されてますので違いは各自把握しておいてください。

参考:CMDとENTRYPOINTの関連について

ここでnginxと言うよりは、Dockerコンテナの特性を理解する上で重要なのがdaemon offの部分です。daemonをoffにしてねとは、バックグラウンドで起動するをoffにしているという意味になります。

Dockerコンテナは「プロセスがフォアグラウンドで起動していないとコンテナは終了する」という特性があります。

なので、nginxをバックグラウンドで起動してもすぐに落ちてしまうのでフォアグラウンドで起動してねと明示してあげます。

わりと初心者が陥りやことなので覚えておきましょう。

index.htmlファイルの作成

次にindex.htmlファイルを作成していきます。と言っても、凝ったものは作るつもりがないので、以下のようなものを作りました。

<!DOCTYPE html>
<html>
<head>
<title>Welcome to DISCO MONSTER!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to DISCO MONSTER!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

はい、最初に完成形イメージとして表示しましたが、あまり芸が無いですが「Welcome to nginx!」を「Welcome to DISCO MONSTER!」にしました。

これで以上です。

実践

それでは、これら作成したファイルをもとにオリジナルイメージを作っていきましょう。

Dockerfileからイメージを作成する
% docker build -t ${REPO}:${TAG} .

最後の「.」を忘れないでください。

これは、カレントディレクトリのDockerfileをビルドするという意味です。

また、-tでタグ名を指定してビルドするというオプションになります。

例:カレントディレクトリのDockerfileを「my-nginx:v1.0」というリポジトリ名、タグ名でビルドする

% docker build -t my-nginx:v1.0 . 
---
[+] Building 14.8s (9/9) FINISHED                                                                                                                                                           
 => [internal] load .dockerignore                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                        0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                   0.0s
 => => transferring dockerfile: 198B                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/ubuntu:20.04                                                                                                                        1.8s
 => [1/4] FROM docker.io/library/ubuntu:20.04@sha256:cf31af331f38d1d7158470e095b132acd126a7180a54f263d386da88eb681d93                                                                  0.0s
 => [internal] load build context                                                                                                                                                      0.0s
 => => transferring context: 31B                                                                                                                                                       0.0s
 => CACHED [2/4] RUN apt-get update                                                                                                                                                    0.0s
 => [3/4] RUN apt-get install -y nginx                                                                                                                                                12.2s
 => [4/4] COPY ./index.html /var/www/html                                                                                                                                              0.0s
 => exporting to image                                                                                                                                                                 0.7s
 => => exporting layers                                                                                                                                                                0.7s
 => => writing image sha256:a63eee4b051fd860b743477ee3a15ee263710da944540a153f58701aa9af1421                                                                                           0.0s 
 => => naming to docker.io/library/my-nginx:v1.0                                                                                                                                       0.0s 

完了すると、FINISHEDと表示されます。

実際に、イメージを確認すると作られています。

% docker images
---
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
my-nginx            v1.0                70f9143cc4ae        9 seconds ago       160MB
イメージからコンテナを立ち上げる
% docker run -itd -p ${LOCAL_PORT}:${COTAINER_PORT} ${REPO}:${TAG}

続いてコンテナdocker runは前回の記事でも使っているのコマンドなの説明は省略します。

ここで、ポイントなのは-pのオプションにより、「現実世界のポートとコンテナ世界のポートを変換する」ということです。

先ほど述べた、「コンテナ世界”としては“」ってやつです。

コンテナ世界としては80ポート開けたけど現実世界のどのポートと紐付けるかはコンテナ起動時に指定します。

例:現実世界の80ポートからコンテナ世界の80ポートへ変換する

% docker run -itd -p 80:80 my-nginx:v1.0
---
70f9143cc4ae0a996b76d6055da3315cb1241a44ad97b0e88e544d2dae4c4a63

これで立ち上げまで終わりました。準備完了です。

動作確認

実際に動作確認していきます。

まずは、dockerのプロセスを確認します。

% docker ps
---
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
70f9143cc4ae        my-nginx:v1.0       "nginx -g 'daemon of…"   57 seconds ago      Up 56 seconds       0.0.0.0:80->80/tcp   serene_chatelet

うん、無事に起動してますね。

また、コンテナのPORTの部分が0.0.0.0:80->80/tcpと80ポートから80ポートへ変換されていることがわかります。

次にコンテナの中に入ってみましょう。

そして、/var/www/htmlにコピーしたファイルがあるか確認しましょう。

% docker exec -it 70f9143cc4ae /bin/bash
---
root@70f9143cc4ae:~# ls -l /var/www/html/
total 8
-rw-r--r-- 1 root root 612 Apr 23 09:02 index.html
-rw-r--r-- 1 root root 612 Apr 24 02:16 index.nginx-debian.html

ちゃんとindex.htmlが入ってますね。ちなみに、index.nginx-debian.htmlがデフォルトで入っていたファイルです。

最後にブラウザ上でlocalhostと入力してみましょう。

はい、上のような画面が出たらOKです。

以上、Dockerfileからオリジナルnginxのイメージを作る方法でした。

コメント

タイトルとURLをコピーしました