Docker 学習 #2:Dockerfileを学ぶ

Dockerfileを学ぶ

以下記事を参考にDockerfileを使ってみる。
Dockerfileとdocker buildコマンドでDockerイメージの作成

環境

Windows 11 25H2 (26200.8037)

WSLバージョン
PS C:\Users\xxx> wsl --version
WSL バージョン: 2.3.24.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.65
MSRDC バージョン: 1.2.5620
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.8037

Ubuntuバージョン
xxx@xxx:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble

手順

基本的には「Docker 学習 #1 コンテナの作成から実行までやってみる」で行なった内容をDockerfile化する、という流れである。

1. 作業フォルダ作成

Ubuntu上に"nginx1"という作業フォルダを作成する。(フォルダ名は何でも良い)
mkdir nginx1
cd nginx1

実行結果:
root@xxx:~# mkdir nginx1
root@xxx:~# cd nginx1      
    

2. Dockerfile作成

"Dockerfile"というファイル名に新規にファイルを作成し以下内容を記述する。
FROM ubuntu
MAINTAINER takipone <xxxx@gmail.com>
RUN apt-get install -y nginx
ADD index.html /usr/share/nginx/html/

参考サイトではvimで編集しているが、今回はVSCodeのリモートエクスプローラーで編集を行なった。

前回 "apt-get update" を先に実行しておかないと nginxのインストールができなかったので、多分上記ではうまく行かないと思うがとりあえずサンプルのままやってみる。

3. テスト用htmlファイル作成

作業フォルダにテスト用html(index.html)を作成する。

echo 'Hello!' > index.html

私の場合は、2.と同じくVSCodeを使い、nginx1¥index.htmlファイルを作成、内容として「Hello!」を書き込んだ。

3. フォルダ構成確認

nginx1フォルダには "Dockerfile"と"index.html"の2つが存在する状態である。

実行結果:

root@xxx:~/nginx1# ls
Dockerfile  index.html
      

4. Dockerイメージ作成

docker buildコマンドを使いDockerイメージを作成する。
作成するイメージ名を -t(または--tag)オプションで指定し、名前は "takipone/nginx"、タブ名は "1.0" とする。(何でも良い)
docker build -t takipone/nginx:1.0 .

実行結果:

root@xxx:~/nginx1# docker build -t takipone/nginx .
[+] Building 6.2s (6/7)                                                                      docker:default
 => [internal] load build definition from dockerfile                                                   0.0s
 => => transferring dockerfile: 153B                                                                   0.0s
 => WARN: MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2)  0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                       2.1s
 => [internal] load .dockerignore                                                                      0.0s
 => => transferring context: 2B                                                                        0.0s
 => [1/3] FROM docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103  3.6s
 => => resolve docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103  0.0s
 => => sha256:689b91d88a0f4086057ec826027b128902ecf2b516be510371c115bc55da19a6 29.73MB / 29.73MB       3.1s
 => => extracting sha256:689b91d88a0f4086057ec826027b128902ecf2b516be510371c115bc55da19a6              0.4s
 => [internal] load build context                                                                      0.0s
 => => transferring context: 44B                                                                       0.0s
 => ERROR [2/3] RUN apt-get install -y nginx                                                           0.4s
------
 > [2/3] RUN apt-get install -y nginx:
0.288 Reading package lists...
0.292 Building dependency tree...
0.293 Reading state information...
0.293 E: Unable to locate package nginx
------

 1 warning found (use docker --debug to expand):
 - MaintainerDeprecated: Maintainer instruction is deprecated in favor of using label (line 2)
dockerfile:3
--------------------
   1 |     FROM ubuntu
   2 |     MAINTAINER takipone 
   3 | >>> RUN apt-get install -y nginx
   4 |     ADD index.html /usr/share/nginx/html/
   5 |
--------------------
ERROR: failed to build: failed to solve: process "/bin/sh -c apt-get install -y nginx" did not complete successfully: exit code: 100
      

"apt-get install -y nginx"の行でエラーになったので、やはり "apt-get update" が必要なんだと思う。ということで以下のように変更。

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

&& は apt-get updateが成功したら次を実行、という意味で、Dockerではこの形式で指定するのが推薦だそう。
RUNコマンドを2行に分けて記述するとそれぞれが別レイヤーとなり、思わぬキャッシュを使うなどしてバグの原因になる(by ChatGPT)らしい。

また、2行目の"MAINTAINER"で警告が発生。
https://docs.docker.jp/engine/reference/builder.html によるとMAINTAINERは非推薦で、代替としてLABEL命令を使え、とのこと。
MAINTAINERフィールドに相当するラベルは、以下のように指定する。

LABEL maintainer="xxx@gmail.com"

上記を踏まえ、Dockerfileを以下のように修正する。

FROM ubuntu
LABEL maintainer="xxxx@gmail.com"
RUN apt-get update && apt-get install -y nginx
ADD index.html /usr/share/nginx/html/

再度 docker build を実行する。

docker build -t takipone/nginx:1.0 .

実行結果:

root@xxx~/nginx1# docker build -t takipone/nginx:1.0 .
[+] Building 17.9s (8/8) FINISHED                                                            docker:default
 => [internal] load build definition from Dockerfile                                                   0.0s
 => => transferring dockerfile: 170B                                                                   0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                       1.1s
 => [internal] load .dockerignore                                                                      0.0s
 => => transferring context: 2B                                                                        0.0s
 => CACHED [1/3] FROM docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831cc  0.1s
 => => resolve docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103  0.0s
 => [internal] load build context                                                                      0.0s
 => => transferring context: 31B                                                                       0.0s
 => [2/3] RUN apt-get update && apt-get install -y nginx                                              13.8s
 => [3/3] ADD index.html /usr/share/nginx/html/                                                        0.1s
 => exporting to image                                                                                 2.5s
 => => exporting layers                                                                                1.8s
 => => exporting manifest sha256:13cc310082b1a95a8d72b255c885a242dddc590222ea41894284691d2ad0dc3f      0.0s
 => => exporting config sha256:8c0db8b83f49fc5567911598b09335e05f8c3e3f0f96b5962cec25ce48b5719b        0.0s
 => => exporting attestation manifest sha256:66ab69b59bd4fd7f88ca34c329c841e5c427da22446fe40643a8e02b  0.1s
 => => exporting manifest list sha256:c979f07e3ccc99200cbbc283e752b438fb4b8a6a83abd8b8696424fa4c635fd  0.0s
 => => naming to docker.io/takipone/nginx:1.0                                                          0.0s
 => => unpacking to docker.io/takipone/nginx:1.0                                                       0.4s
      
うまくいったようだ。

5. イメージ確認

docker imagesコマンドでイメージが作成されたことを確認。

root@xxx:~/nginx1# docker images
                                                                                        i Info →   U  In Use
IMAGE                                    ID             DISK USAGE   CONTENT SIZE   EXTRA
takipone/nginx:1.0                       c979f07e3ccc        231MB         74.7MB
      

6. コンテナ実行

作成したDockerイメージをdocker runで実行してみる。

docker run -d -p 80:80 --name nginx1 takipone/nginx:1.0 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

実行結果:

root@xxx:~/nginx1# docker run -d -p 80:80 --name nginx1 takipone/nginx:1.0 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
2bd815cbf7f8d7f925d2f5a179cf715c5561ea96dca99f940c8c9f315e964f6a
      

curlコマンドで動作確認。

curl localhost

実行結果: Hello! と表示されるはずが nginx標準のindex.htmlが表示されてしまっている。

root@xxx:~/nginx1# curl localhost



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

7. Dockerfile修正

先ほど思った動作にならなかったのは index.htmlの格納先を /usr/share/nginx/html/ として指定していたのが原因。
正しくは /var/www/html/ とのこと。

また、ファイルのコピーだけであればADDではなくCOPY命令を使った方がいいらしい。
(参考:Docker のベストプラクティス: Dockerfile の ADD 命令と COPY 命令の違いを理解する)
ということでADD命令をCOPY命令へ変更する。

修正後のDockerfile:

FROM ubuntu
LABEL maintainer="xxxx@gmail.com"
RUN apt-get update && apt-get install -y nginx
COPY index.html /var/www/html/

起動中コンテナ停止、削除から再度コンテナの実行までを行う。

docker stop nginx1
docker rm nginx1
docker rmi takipone/nginx:1.0
docker build -t takipone/nginx:1.0 .
docker run -d -p 80:80 --name nginx1 takipone/nginx:1.0 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
curl index.html
root@xxx:~/nginx1# docker stop nginx1
nginx1
root@xxx:~/nginx1# docker rm nginx1
nginx1
root@xxx:~/nginx1# docker rmi takipone/nginx:1.0
Untagged: takipone/nginx:1.0
Deleted: sha256:c979f07e3ccc99200cbbc283e752b438fb4b8a6a83abd8b8696424fa4c635fd5
    
root@xxx:~/nginx1# docker build -t takipone/nginx:1.0 .
[+] Building 2.8s (8/8) FINISHED                                                             docker:default
 => [internal] load build definition from Dockerfile                                                   0.0s
 => => transferring dockerfile: 162B                                                                   0.0s
 => [internal] load metadata for docker.io/library/ubuntu:latest                                       1.5s
 => [internal] load .dockerignore                                                                      0.0s
 => => transferring context: 2B                                                                        0.0s
 => [1/3] FROM docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103  0.1s
 => => resolve docker.io/library/ubuntu:latest@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103  0.1s
 => [internal] load build context                                                                      0.0s
 => => transferring context: 31B                                                                       0.0s
 => CACHED [2/3] RUN apt-get update && apt-get install -y nginx                                        0.0s
 => [3/3] COPY index.html //var/www/html/                                                              0.1s
 => exporting to image                                                                                 0.8s
 => => exporting layers                                                                                0.2s
 => => exporting manifest sha256:134387c39e899fafa193bf37a94a00303cd4dcc1ca87af8245c6d7c4d990b872      0.0s
 => => exporting config sha256:edc638c3b0d7aae863f5554af9dd0404a504fd0d76e0a8b1def16caa20e0b4d4        0.0s
 => => exporting attestation manifest sha256:138e8eeb22d6e4f0c5aa36fef4ac1771724f9b57aaaffbc65275ebcb  0.1s
 => => exporting manifest list sha256:0e7cfd872fc98478c614b234a5c1fe718decac28ea9b8d9bb44bdfaba2d5619  0.0s
 => => naming to docker.io/takipone/nginx:1.0                                                          0.0s
 => => unpacking to docker.io/takipone/nginx:1.0                                                       0.4s
    
root@xxx:~/nginx1# docker run -d -p 80:80 --name nginx1 takipone/nginx:1.0 /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf
b336b6287d8caa0d3d60df81e4d0604b304a056bd0e341474a69a3502e0c57bc
    

うまくいった。

root@xxx:~/nginx1# curl localhost
Hello!
    
長くなったので次回に続ける。


Docker 学習

0 件のコメント:

その他の記事