はじめに
Dockerに慣れ親しんできて、「そろそろ復数のDockerイメージ・コンテナを使って開発するかー」というレベルの方は多いかと思います。
私もその一人なのですが、いざリファレンスを読みながら使ってみても上手く扱えずに開発が滞ってしまうことがありました。
今回は、そのなかでも一番基本的で、かつわからないと結構ドツボにハマるdocker-compose up
についての解説を書いてみました。
自身も初学者ですので、もし誤りがあればご指摘いただけると助かります。
前提
今回はコマンドの説明のために、1つのコンテナを起動させるシンプルなプロジェクトを想定してみます。
ディレクトリ構成
.
├── Dockerfile
├── docker-compose.yml
├── file.txt
└── file2.txt
Dockerfile、docker-compose.ymlの内容
FROM ubuntu:18.04
WORKDIR work
ADD ./file.txt /work/file.txt
CMD ["ls"]
version: '3.7'
services:
test:
build: .
image: my-alpine-image
container_name: my-apline
とりあえず"up"してみよう
上記の構成でdocker-compose up
をしてみると何が起こるか確認しましょう。
$ docker-compose up
Building test
// Stepは省略
Successfully built ff8e7d96a995
Successfully tagged my-alpine-image:latest
WARNING: Image for service test was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating my-apline ... done
Attaching to my-apline
my-apline | file.txt
my-apline exited with code 0
ここで重要なのは次の2点です。
-
my-alpine-image
というイメージを作成している -
my-alpine
というコンテナを作成している
つまりはdocker run
と同じです。実際にイメージやコンテナを確認してみます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d14fde119f0 my-alpine-image "/bin/bash" 10 minutes ago Exited (0) 10 minutes ago my-apline
$ REPOSITORY TAG IMAGE ID CREATED SIZE
my-alpine-image latest ff8e7d96a995 10 minutes ago 64.2MB
またコンソールにはmy-apline | file.txt
と出力されているように、file.txtが含まれていることもわかります。
復数コンテナであってもこの動きは変わりません。そのため、ここで「なるほど、DockerComposeは理解した」となり、このあとの勘違いにつながります。
Dockerfileを修正してもう一度upしてみる
つぎにDockerfileを修正して、test2.txtもコンテナに含めるようにしましょう。
FROM ubuntu:18.04
WORKDIR work
ADD ./file.txt /work/file.txt
ADD ./file2.txt /work/file2.txt
CMD ["ls"]
さて、docker-compose up
を実行してみます。すると次のような結果になりました。
$ docker-compose up
Starting my-apline ... done
Attaching to my-apline
my-apline | file.txt
my-apline exited with code 0
出力を見ればわかるように、コンテナ(my-apline)にtest2.txtが含まれていません。
なぜなら今回のdocker-compose up
は、さきほど作成したコンテナをただ起動しただけだからです。
その証拠に、コンテナとイメージを確認しても変わりがないことが見てとれます。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6d14fde119f0 my-alpine-image "/bin/bash" 10 minutes ago Exited (0) 10 minutes ago my-apline
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-alpine-image latest ff8e7d96a995 10 minutes ago 64.2MB
どのようにup
すべきだったか
では、どうすればtest2.txtを含んだ、最新のイメージを使ったコンテナになるのでしょうか。
正解は、「再度ビルドする」ことを明示する--build
オプションを使うことです。
$ docker-compose up --build
Building test
// Stepは省略
Successfully built 7218cdd4f17a
Successfully tagged my-alpine-image:latest
Recreating my-apline ... done
Attaching to my-apline
my-apline | file.txt
my-apline | file2.txt
my-apline exited with code 0
イメージもコンテナも新しくなっていることがわかります。
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
28c26826bf20 my-alpine-image "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago my-apline
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-alpine-image latest 7218cdd4f17a About a minute ago 64.2MB
まとめ
まとめると、docker-compose up
というコマンドは、
- まだイメージが作成されていなければ、イメージを作成して、さらにコンテナを作成・起動する
- すでにコンテナが存在すれば、イメージ・コンテナの再作成は行わず、(停止中の)コンテナを起動するだけ
ということがわかりました。
ちなみにイメージがない状態でdocker-compose up
するとコンソールに、
Image for service test was built because it did not already exist. To rebuild this image you must use
docker-compose build
ordocker-compose up --build
.
(サービステスト用のイメージが存在しなかったためにビルドされました。このイメージを再構築するにはdocker-compose build
かdocker-compose up --build
を使う必要があります。)
と出ていたことに気づきました。英語をちゃんと読めばこんなに迷う必要はなかったですね。
似たような箇所でつまづいた人たちの参考になれば幸いです!