1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerで色々やってみる(DockerFile編)

Posted at

概要

Dockerのインストール、Image、Containerの基本的なところを整理してきましたが、今回はとうとうDockerfileを「自己整理」してみようと思います。

前提条件

  • Windows10にDocker Desktopがインストールされている状態

Dockerfileとは?

Dockerfileとは、dockerの「build」コマンドを使う際に登場します。

今までの説明では、DockerHubからImageをpullしてきて、Containerを作り、そのContainerをいじるような流れでした。
「Containerは簡単に作れるが、ImageにはないものをContainerを作成するたびにインストールしたり設定したりするのは面倒なんだけど」

ということになります。
こうなると、「だったらImage自体を改変したい」ってなりますね。

例えば、前回の「httpd」ですが、Debian系、Alpine系しかないけど、Redhat系で作りたい。とか
使用するmoduleを最初から設定しておきたい。とか、、、、

Dockerfileは、pullしてきたImageを「ベース」として、自分用のImageを作るためのスクリプトファイルとなります。

Dockerfileの書式~buildまで

Dockerfileの書式リファレンス

まずは、Dockerfileの書式です。

やってみる(httpd)

それでは、まずは前回のApache httpdをDockerfileでやっていこうと思います。
その前に、ローカルのImageやContainerを全部消しておきます。(ここでは、もうゴミ扱い)
※Containerは停止させておいてください。

powershell
PS C:\> docker rm $(docker ps --filter status=exited -q)
PS C:\> docker rmi $(docker images -q)

これで、ImageとContainerは全て消えたはず。

powershell
PS C:\> docker ps -all
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
PS C:\> docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
PS C:\>

それでは、やっていきましょう。
まずは、Cドライブ直下に作業用のフォルダを作成します。

powershell
PS C:\> mkdir c:\docker_works\httpd


    ディレクトリ: C:\docker_works


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/06/20     01:37                httpd


PS C:\>

前回、httpdのImageをpullしてきて、Containerを起動した流れをおさらいします。

powershell
PS C:\> docker pull httpd:latest
PS C:\> docker run -d -p 8080:80 httpd

こんな感じでした。

続いて、メモ帳を開いて(私はサクラエディタを使ってますが)下記を「Dockerfile」という名前で作成したhttpdフォルダへ保存します。

Dockerfile
FROM httpd:latest

続いて、「build」コマンドでImageを作成します。

powershell
PS C:\> cd .\docker_works\httpd\
PS C:\docker_works\httpd> docker build -t my_httpd .
[+] Building 8.1s (5/5) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 56B                                                                                0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/httpd:latest                                                    3.5s
 => [1/1] FROM docker.io/library/httpd:latest@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9300c69e  4.5s
 => => resolve docker.io/library/httpd:latest@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9300c69e  0.0s
 => => sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9300c69ee729 1.86kB / 1.86kB                     0.0s
 => => sha256:91b8f2e89503a8d3ee1aff392a1df086c7517b6448c29c24c68139c59831619c 1.37kB / 1.37kB                     0.0s
 => => sha256:b260a49eebf92310bc8a6024591cb5c7846ca47ca30106a43d015c381bf87633 9.04kB / 9.04kB                     0.0s
 => => sha256:42c077c10790d51b6f75c4eb895cbd4da37558f7215b39cbf64c46b288f89bda 31.38MB / 31.38MB                   2.0s
 => => sha256:77a357ba66a85136c310c166c751585c8795e74205806bf582209dc6f98704af 175B / 175B                         1.5s
 => => sha256:e9e2f87fc2cee5b3637255fd803d453cb13fa64fee5793272d27d10115741251 1.72MB / 1.72MB                     1.4s
 => => sha256:de91965861a5e63599ec202f7bc8a09f0a6b74dd1c1a023816903bbc2cf58c83 300B / 300B                         1.7s
 => => sha256:0b3c9bceb738771188edcce310e347b0799670cd65689d9908d543c4d16ff12b 23.97MB / 23.97MB                   3.7s
 => => extracting sha256:42c077c10790d51b6f75c4eb895cbd4da37558f7215b39cbf64c46b288f89bda                          1.0s
 => => extracting sha256:77a357ba66a85136c310c166c751585c8795e74205806bf582209dc6f98704af                          0.0s
 => => extracting sha256:e9e2f87fc2cee5b3637255fd803d453cb13fa64fee5793272d27d10115741251                          0.1s
 => => extracting sha256:0b3c9bceb738771188edcce310e347b0799670cd65689d9908d543c4d16ff12b                          0.5s
 => => extracting sha256:de91965861a5e63599ec202f7bc8a09f0a6b74dd1c1a023816903bbc2cf58c83                          0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:882cc4d4cf13db875e044d8ea549ddaaa23924bf10a51082ff3049e2fd3b908f                       0.0s
 => => naming to docker.io/library/my_httpd                                                                        0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

作成したImageを確認してみます。

powershell
PS C:\docker_works\httpd> docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
my_httpd     latest    882cc4d4cf13   5 days ago   145MB

ふむ。
Containerを生成して実行してみます。

powershell
PS C:\docker_works\httpd> docker run -d -p 8080:80 my_httpd
e05c95d476879a0b3d53866840eee44ea4bf7234b68a32c9cee2390038b2d49b
PS C:\docker_works\httpd>

Docker Desktopで確認してみます。
image.png

実際にブラウザでアクセスしてみましょう。
image.png

ふむ、まずはOK。
Containerを停止しておきます。

powershell
PS C:\docker_works\httpd> docker ps --all
CONTAINER ID   IMAGE      COMMAND              CREATED         STATUS         PORTS                  NAMES
e05c95d47687   my_httpd   "httpd-foreground"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->80/tcp   unruffled_hamilton
PS C:\docker_works\httpd> docker stop e05c95d47687
e05c95d47687
PS C:\docker_works\httpd>

ステップアップ

体裁を整える

Dockerfileには、行頭に「#」を記載すればコメントアウトとして扱われます。
また、Imageの作成者(管理者)などの情報を書いたりできます。
せっかくDockerfileに色々用意されているので、使っていきましょう。

Dockerfile
# 利用するTAGを指定
ARG VERSION=latest

# Hubからhttpdを取得
# https://hub.docker.com/_/httpd
FROM httpd:$VERSION

# 80番を公開する
EXPOSE 80

# 付属情報、LABELを増やすとレイヤーが増えるので1つにまとめておく
LABEL version="1.0" \
      description="Modify sample httpd."

上書きして、build。一応、TAGに「latest」を付けておきました。

powershell
PS C:\docker_works\httpd> docker build -t my_httpd:latest .
[+] Building 2.4s (5/5) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 371B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/httpd:latest                                                    2.3s
 => CACHED [1/1] FROM docker.io/library/httpd:latest@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9  0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:b1d643053f9664042cc2bdc33df6dc82c956ab377f9468b0f12fa37885ec3884                       0.0s
 => => naming to docker.io/library/my_httpd:latest                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

さて、ここから注意しておくことを書いておきます。

先ほど、「run」したContainerをなぜ「廃棄」せずに「停止」していたのか。
分かりやすいように、Docker Desktopの画面で見ましょう。

image.png

一見すると、なんともないですね。
でも、Containerを生成した際に使ったImageは、さっき更新しましたよね?
ということは、このContainerもImageの更新が自動的に反映されるのでしょうか・・・・?

答えは「No」です。
「my_httpd」のリンクをクリックすると
image.png

Image名のところが「<none>:<none>」になってますね。

では、Imagesのリストは?
image.png

更新されたImageに紐づいたContainerは「無い」ことになっていて、<none>に紐づくContainerがあることになっています。

実は、この状況はよくあることで、Docker Hubから取得したImageを使ってContainerを生成して使っていた時は良いのですが、何かのタイミングで
DockerHubから再度同じImageを取得して更新すると、使用中のContainerが紐づくImageがなくなってしまうようになります。

imagesコマンドで見るとこうなります。

powershell
PS C:\docker_works\httpd> docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
<none>       <none>    882cc4d4cf13   5 days ago   145MB
my_httpd     latest    b1d643053f96   5 days ago   145MB

この個数で、何をやっていたかわかっている場合は良いのですが、いろいろやっていてImageがどんどん増えてきて、「不要なImageを消すか」と思い立って削除しようとすると、「使用中(Containerがある)」なので削除できない。と言われ、どのContainerがこのImageを使っているのか特定できねぇ・・・となって、Containerをバシバシ消していると必要なContainerまで消してしまった。みたいなこともありましたw。

「It works!」を変更する(上書き編)

動作確認で表示したページ「http://localhost:8080 」には「It works!」と表示されていました。

このテキストは、下記にindex.htmlとしておかれています。

sh
# cd /usr/local/apache2/htdocs/
# ls -al
total 16
drwxr-xr-x 2 root     root     4096 Jun 13 23:35 .
drwxr-xr-x 1 www-data www-data 4096 Jun 13 23:35 ..
-rw-r--r-- 1      504 staff      45 Jun 11  2007 index.html
# cat index.html
<html><body><h1>It works!</h1></body></html>

ということで、「index.html」を別途用意して、これをImageの作成時に上書きしてしまいましょう。

index.html
<html><body><h1>It MY works!</h1></body></html>

作成したindex.htmlは「C:\docker_works\httpd\cp_public_html」フォルダを作成して、その中に入れておきます。

それでは、再度Dockerfileを編集します。

Dockerfile
# 利用するTAGを指定
ARG VERSION=latest

# Hubからhttpdを取得
# https://hub.docker.com/_/httpd
FROM httpd:$VERSION

# 【追加】自作のindex.htmlを配置する
COPY ./cp_public_html/index.html /usr/local/apache2/htdocs/

# 80番を公開する
EXPOSE 80

# 付属情報、LABELを増やすとレイヤーが増えるので1つにまとめておく
LABEL version="1.0" \
      description="Modify sample httpd."

buildします。

powershell
PS C:\docker_works\httpd> docker build -t my_httpd:latest .
[+] Building 2.5s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 472B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/httpd:latest                                                    2.3s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 137B                                                                                  0.0s
 => CACHED [1/2] FROM docker.io/library/httpd:latest@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9  0.0s
 => [2/2] COPY ./cp_public_html/index.html /usr/local/apache2/htdocs/                                              0.0s
 => exporting to image                                                                                             0.0s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:9d7132f0f6218e79ac4f8cf8eb9b3f05c8b4c15cbf3cdf581f6b24aa3ecd6d1b                       0.0s
 => => naming to docker.io/library/my_httpd:latest                                                                 0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them

Containerを生成して起動します。

PS C:\docker_works\httpd> docker run -d -p 8080:80 my_httpd
f11efbec9b379308f04d333c3c9c6de61e3b1a525998b81fbcb8f963d9847261

http://localhost:8080 」へアクセスして表示確認します。
image.png

きちんと上書きされましたね。

「It works!」を変更する(マウント編)

前述の上書き編は、Imageを作成する際の一度きりの変更や配置に使うものですが、Webページのように表示確認して、変更してと繰り返す場合は、ちょっと面倒ですね。
そこで、マウントしてしまう方法があります。

Docker Desktopの「Volumes」に表示される方法ですね。
image.png

それでは、まずはDockerfileのある場所に「public_html」フォルダを作成します。
image.png

このpublic_htmlフォルダ内に適当なindex.htmlを作成して配置します。

index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Docker Test</title>
</head>
<body>
    <h1>TEST</h1>
    <h2>TEST</h2>
    <h3>TEST</h3>
    <h4>TEST</h4>
</body>
</html>

続いて、Containerを生成します。
(マウントは、Image作成ではできません。Containerを作成する際にローカル側のマウント元が実行環境で異なるからです)

PS C:\docker_works\httpd> docker run -d -p 8080:80 -v $pwd/public_html/:/usr/local/apache2/htdocs/ my_httpd
8501144b766c551b86e16b49d1de445e1a6d4e86e7a15c537fff1205d6741a06

Containerを起動したら、「http:localhost:8080」を開いてみます。
無事、マウントできているようです。
image.png

試しに、「docker inspect」してContainerの状態を確認します。

powershell
PS C:\docker_works\httpd> docker inspect 8501144b766c551b86e16b49d1de445e1a6d4e86e7a15c537fff1205d6741a06
[
    {
        "Id": "8501144b766c551b86e16b49d1de445e1a6d4e86e7a15c537fff1205d6741a06",
...
        "HostConfig": {
            "Binds": [
                "C:\\docker_works\\httpd/public_html/:/usr/local/apache2/htdocs/" ←←←←
            ],
            "ContainerIDFile": "",
...
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/run/desktop/mnt/host/c/docker_works/httpd/public_html",←←←←
                "Destination": "/usr/local/apache2/htdocs",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
...

Binds/Mountsの情報内に反映されてますね。

マウントしている状態なので、「public_html」フォルダ内にファイルを追加したり、index.htmlを変更すれば、即時に反映されることになります。
便利ですね。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?