このページで解説している内容は、以下の YouTube 動画の解説で見ることができます。

【Docker入門】イメージの再ビルド

 イメージのビルドにはキャッシュが利用され、ビルドの高速化が図られます。しかし、時にはキャッシュが問題を引き起こすこともあります。そのため、キャッシュを無効にすることも重要な操作となります。

 ここでは、まず、Dockerのビルドについて解説します。その後で、明示的なイメージのビルドを行っていきます

既存のイメージを使用したビルド

 「docker compose up -d」コマンドは、既存のイメージを再ビルドせずにコンテナを起動します。既にビルドされたイメージがある場合は、それを利用します。

明示的なイメージの再ビルド

docker compose build」コマンド

 イメージの再ビルドを明示的に行うには「docker compose build」コマンドを使用します。これにより、Dockerfile内の変更が反映された新しいイメージが構築されます。

docker compose up -d --build」コマンド

 イメージの再ビルドは「docker compose up -d --build」コマンドでも行うことができます。こちらはイメージの再ビルドとコンテナの起動を同時に行います。これにより、コンテナを更新したいときに簡単に行うことができます。

ビルドキャッシュの無効化

 Dockerfileを更新しても、「docker compose build」コマンドを実行しても、Dockerfileの変更内容が反映されない場合があります。Dockerは、ビルドプロセスにおいてキャッシュを使用して高速化を図ります。そのため、Dockerfile内の変更が反映されないことがあります。これを避けるには、「--no-cache」オプションを使用してキャッシュを無効にする必要があります。

docker compose build --no-cache」コマンド

docker compose build --no-cache」を実行すると、キャッシュを無視してすべてのステップが再実行されます。そのため、ビルドに時間がかかる可能性がありますが、変更内容が正しく反映されます。

明示的な再ビルド操作の実演

Dockerのビルドの特徴について理解できたところで、Dockerの再ビルドを行っていきましょう。

不要なDockerオブジェクトの削除

まず、不要なDockerオブジェクトをすべて削除しておきます。

以下のコマンドを実行します。

・「docker system prune -a」コマンドを実行します。

Are you sure you want to continue? [y/N] の質問には「y」と入力します。

PS C:\Users\joeac> docker system prune -a
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all images without at least one container associated to them
  - all build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
994c86668250f933b1c786acaaf0c6e9942274a31aec210cd56064c86d64c5c0

Deleted Networks:
flask1_default

Deleted Images:
untagged: flask1-flaskweb1:latest
deleted: sha256:7a06d1fab4fab0600082edf421fa2a2444edce672a039c35965acad6e8d578ff

Deleted build cache objects:
surfffqo62squp379ed79hcej
ng27y0z2qqyd3kv5fj2m8k2pt
r4ip04rk8tqm6n3en8jva2gxr
cndun344ol33du032q2022tq5
uzb6yz14k2hbesr8d3oeb4yi5
skfj9dgj4qvfbh9foivymfus7
kx4so99ad0ewx7m0wqfa9ygze
gxhsr0eh20xvp90qrhxe9q9sx
guzm3yti0im19tmiqx8gmm6z4
4x60ikp9xrfb52y4qpg7iwfx4
t7xchg6mneevsnrp91f7lnoum
j1my2x7ijzk8a18aly5dog6k4

Total reclaimed space: 15.27MB

・「docker system prune -a」コマンドで削除されなかったDockerオブジェクトは、個別に削除しておきます。

環境によって削除されずに残っているDockerオブジェクトは異なります。

Dockerfileの作成

Dockerfileを作成します。

ディレクトリの作成と移動

 Docker Composeでコンテナを作成するには、「compose.yaml」ファイルが必要になります。今回は「Dockerfile」も使用します。

 デフォルトでは、カレントディレクトリにある「compose.yaml」が読み込まれるため、作業ディレクトリに移動しておきます。

・「cd desktop/docker」コマンドを実行します。

PS C:\Users\joeac> cd desktop/docker
PS C:\Users\joeac\Desktop\docker>

 「flask1」ディレクトリを作成して、作成したディレクトリに移動します。次のコマンドを実行します。

  • 「mkdir flask2」コマンド
  • 「cd flask2」コマンド
PS C:\Users\joeac> cd desktop/docker
PS C:\Users\joeac\Desktop\docker> mkdir flask2

    Directory: C:\Users\joeac\Desktop\docker

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2024/04/11     0:05                flask2

PS C:\Users\joeac\Desktop\docker> cd flask2
PS C:\Users\joeac\Desktop\docker\flask2>

VSCodeの起動

VSCodeで「Dockerfile」ファイルを作成します。

・「code Dockerfile」コマンドを実行します。

PS C:\Users\joeac\Desktop\docker\flask2> code Dockerfile

VSCodeが起動します。

「Dockerfile」ファイルの編集

・「Dockerfile」ファイルを以下のように編集して保存します。

FROM python:3.12
WORKDIR /usr/src/app
RUN pip install flask==3.0.2
CMD ["flask", "run", "--host=0.0.0.0"]

Flaskアプリケーションを格納するディレクトリの作成

Flaskアプリケーションを格納する「src」ディレクトリを作成します。

・「mkdir src」コマンドを実行します。

PS C:\Users\joeac\Desktop\docker\flask1> mkdir src

    Directory: C:\Users\joeac\Desktop\docker\flask1

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----          2024/04/07    23:53                src

作成した「src」ディレクトリの中にFlaskアプリケーションを格納していきます。

Flaskアプリケーションの作成

 以下は、簡単なFlaskアプリケーション「app.py」です。このアプリケーションでは、ルートURL(”/”)にアクセスすると「Hello, World!」というメッセージを表示します。

from flask import Flask

# Flaskアプリケーションのインスタンスを作成
app = Flask(__name__)

# ルートURLに対する処理を定義
@app.route("/")
def hello():
    return "Hello World!"

# アプリケーションを実行
if __name__ == "__main__":
    app.run(debug=True)

「app.py」の保存

・「code ./src/app.py」コマンドを実行し、上のプログラムを入力して保存します。

「compose.yaml」ファイルの作成

「compose.yaml」ファイルの内容は以下のとおりです。

services:
  flaskweb2:
    build: .
    environment:
      FLASK_ENV: development
    ports:
      - "5000:5000"
    volumes:
      - ./src:/usr/src/app

「code compose.yaml」の保存

・「code compose.yaml」コマンドを実行し、上の内容を入力して保存します。

Flaskコンテナの作成と実行

Flaskコンテナの作成して、実行します。

・「docker compose up -d」コマンドを実行します。

PS C:\Users\joeac\Desktop\docker\flask2> docker compose up -d
2024/04/11 00:36:04 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed
2024/04/11 00:36:04 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed
[+] Building 17.6s (8/8) FINISHED                                                                        docker:default
 => [flaskweb2 internal] load build definition from Dockerfile                                                     0.0s
 => => transferring dockerfile: 145B                                                                               0.0s
 => [flaskweb2 internal] load metadata for docker.io/library/python:3.12                                           2.3s
 => [flaskweb2 auth] library/python:pull token for registry-1.docker.io                                            0.0s
 => [flaskweb2 internal] load .dockerignore                                                                        0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [flaskweb2 1/3] FROM docker.io/library/python:3.12@sha256:c36bf5e7d0b53c5df102b72272cde8c1fd5defa227d9adb02b  11.4s
 => => resolve docker.io/library/python:3.12@sha256:c36bf5e7d0b53c5df102b72272cde8c1fd5defa227d9adb02bb42182b5b6a  0.0s
 => => sha256:820d3e64c42701d7f97a1137a43e3a3a204ff531c0afe297057fa9dbbba20d1e 7.10kB / 7.10kB                     0.0s
 => => sha256:71215d55680cf0ab2dcc0e1dd65ed76414e3fb0c294249b5b9319a8fa7c398e4 49.55MB / 49.55MB                   1.9s
 => => sha256:c36bf5e7d0b53c5df102b72272cde8c1fd5defa227d9adb02bb42182b5b6accd 2.14kB / 2.14kB                     0.0s
 => => sha256:b2dba524903ec2aee1b131aecb9e1cd5c33051e3885a802b3f64a243753048d9 2.01kB / 2.01kB                     0.0s
 => => sha256:3cb8f9c23302e175d87a827f0a1c376bd59b1f6949bd3bc24ab8da0d669cdfa0 24.05MB / 24.05MB                   1.7s
 => => sha256:5f899db30843f8330d5a40d1acb26bb00e93a9f21bff253f31c20562fa264767 64.14MB / 64.14MB                   3.0s
 => => sha256:567db630df8d441ffe43e050ede26996c87e3b33c99f79d4fba0bf6b7ffa0213 211.14MB / 211.14MB                 6.4s
 => => sha256:d68cd2123173935e339e3feb56980a0aefd7364ad43ca2b9750699e60fbf74c6 6.39MB / 6.39MB                     2.5s
 => => extracting sha256:71215d55680cf0ab2dcc0e1dd65ed76414e3fb0c294249b5b9319a8fa7c398e4                          1.6s
 => => sha256:ce59dbed37c49a0f5f67ad659e630b8628f1c1aac454f81f7fce465132e8201a 22.69MB / 22.69MB                   3.5s
 => => sha256:4967589e05bdc46a90de30b632431f34eeb3abe81dc8617d2523463d365c23bd 246B / 246B                         3.3s
 => => sha256:a5b79de9e00a62bea01c8500fd96fbc13512126f5ccbf19263672665939a0b43 2.70MB / 2.70MB                     3.6s
 => => extracting sha256:3cb8f9c23302e175d87a827f0a1c376bd59b1f6949bd3bc24ab8da0d669cdfa0                          0.4s
 => => extracting sha256:5f899db30843f8330d5a40d1acb26bb00e93a9f21bff253f31c20562fa264767                          1.8s
 => => extracting sha256:567db630df8d441ffe43e050ede26996c87e3b33c99f79d4fba0bf6b7ffa0213                          4.0s
 => => extracting sha256:d68cd2123173935e339e3feb56980a0aefd7364ad43ca2b9750699e60fbf74c6                          0.2s
 => => extracting sha256:ce59dbed37c49a0f5f67ad659e630b8628f1c1aac454f81f7fce465132e8201a                          0.4s
 => => extracting sha256:4967589e05bdc46a90de30b632431f34eeb3abe81dc8617d2523463d365c23bd                          0.0s
 => => extracting sha256:a5b79de9e00a62bea01c8500fd96fbc13512126f5ccbf19263672665939a0b43                          0.2s
 => [flaskweb2 2/3] WORKDIR /usr/src/app                                                                           0.7s
 => [flaskweb2 3/3] RUN pip install flask==3.0.2                                                                   3.1s
 => [flaskweb2] exporting to image                                                                                 0.1s
 => => exporting layers                                                                                            0.1s
 => => writing image sha256:c4b7b33ea1a5b48bb9db9a263c18df1b49793d420e7232b8f226fb501c4cccc0                       0.0s
 => => naming to docker.io/library/flask2-flaskweb2                                                                0.0s
[+] Running 1/2
 - Network flask2_default        Created                                                                           0.5s
 ✔ Container flask2-flaskweb2-1  Started                                                                           0.3s

「Container flask2-flaskweb2-1 Started」と表示されていれば、コンテナが実行され起動しています。

Webブラウザで接続

WebブラウザでFlaskコンテナのFlaskアプリケーションに接続します。

・URLに「http://localhost:5000」と入力します。

「Hello World!」と表示されます。

イメージの再ビルド

「Dockerfile」ファイルの変更

・「Dockerfile」ファイルを以下のように変更して保存します。

「flask==3.0.2」のところを「flask==3.0.3」に変更します。

FROM python:3.12
WORKDIR /usr/src/app
RUN pip install flask==3.0.3
CMD ["flask", "run", "--host=0.0.0.0"]

明示的な再ビルドとコンテナの実行

明示的な再ビルドを行います。

・「docker compose up -d --build」コマンドを実行します。

PS C:\Users\joeac\Desktop\docker\flask2> docker compose up -d --build
2024/04/11 01:06:03 http2: server: error reading preface from client //./pipe/docker_engine: file has already been closed
[+] Building 3.5s (7/7) FINISHED                                                                         docker:default
 => [flaskweb2 internal] load build definition from Dockerfile                                                     0.0s
 => => transferring dockerfile: 145B                                                                               0.0s
 => [flaskweb2 internal] load metadata for docker.io/library/python:3.12                                           0.7s
 => [flaskweb2 internal] load .dockerignore                                                                        0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [flaskweb2 1/3] FROM docker.io/library/python:3.12@sha256:feb6643dfe881d82032b0f6b89babace835152496a85dab55c1  0.0s
 => CACHED [flaskweb2 2/3] WORKDIR /usr/src/app                                                                    0.0s
 => [flaskweb2 3/3] RUN pip install flask==3.0.3                                                                   2.7s
 => [flaskweb2] exporting to image                                                                                 0.1s
 => => exporting layers                                                                                            0.1s
 => => writing image sha256:46f782c4d4743154c844d0b0fd6d60cf835e42609dfb7756f8e339a6b21f2152                       0.0s
 => => naming to docker.io/library/flask2-flaskweb2                                                                0.0s
[+] Running 1/1
 ✔ Container flask2-flaskweb2-1  Started                                                                          11.4s

Flaskコンテナへの接続

Flaskコンテナに接続してFlaskのバージョンを確認します。

・「docker compose exec flaskweb2 pip list」

PS C:\Users\joeac\Desktop\docker\flask2> docker compose exec flaskweb2 pip list
Package      Version
------------ -------
blinker      1.7.0
click        8.1.7
Flask        3.0.3
itsdangerous 2.1.2
Jinja2       3.1.3
MarkupSafe   2.1.5
pip          24.0
setuptools   69.2.0
Werkzeug     3.0.2
wheel        0.43.0

6行目に注目します。「Flask 3.0.3」となっており、Flaskのバージョンが3.03となっています。

 実行している環境によっては、Flaskのバージョンが3.0.2となっている可能性もあります。Flaskのバージョンが更新されていない場合は、ビルドキャッシュを無効化して再ビルドを行います。その際は、「docker compose build --no-cache」コマンドを実行します。