🐳

業務でDocker Composeを使うことになった人のためのマニュアル。

2020/09/30に公開
10

いろんな会社でdockerが使われてきている昨今、なんとなく使ってる人も多いかと思います。
そこで、自分が業務などで利用しているコマンドや説明を書こうと思います。

私のレベルは本番ではdockerを使ってサーバーを立ててる民ではないので、そこまで詳しくないことをご了承ください。

前提

  • dockerほんのちょっとだけ分かる
  • Docker Desktopをすでに入れている状態
  • ローカルで開発している環境をごにょごにょしたい向け

前提認識

コンテナとイメージの違いを理解してないとこのあとの話は把握しにくいかもしれません。
イメージはビルドされたもの(もしくはスナップショット)で、コンテナはイメージを動かしているインスタンスと考えると良いでしょう。
イメージが消えない限りはコンテナを作るのは速いことを覚えておくと良いでしょう。

docker-composeって何よ

docker-composeは複数のdockerコンテナをまとめて管理することができるdockerのためのツールです。
これを使うことである程度dockerの知識が薄くてもいい感じに使うことが出来ます。(私もその一人)

アプリケーションを立ち上げたい

基本的にdocker-composeを使ってるプロジェクトでアプリケーションの各コンテナを立ち上げる場合、まずはdocker-compose.ymlがどこにあるかを確認します。
docker-compose.ymlがどこにあるかわかったら、そのディレクトリに移動してdocker compose up -dで立ち上げることが出来ます。

$ docker compose up -d

-dのオプションはデタッチド・モードと呼ばれ、バックグラウンド上でコンテナを立ち上げるモードです。これをつけてないとログがダラダラと流れ出します。

アプリケーションを落としたい

アプリケーションの各コンテナを落とすにはdocker compose downを利用します。

$ docker compose down

docker compose stopというコマンドもありますが、こちらは立ち上げたコンテナを消さないで保持するコマンドです。ただ、docker-compose.ymlが更新されたときなどに対応できないのでdownが良いでしょう。

downの場合、立ち上げたコンテナを消してますがコンテナを消しているだけでイメージは消していません。基本的にイメージが消えない限りup -dのときにビルドは行われないので速度面なども気にする必要はありません。

アプリケーションを再起動したい

アプリケーションを再起動したい場合はrestartというコマンドが存在します。

$ docker compose restart

restartはマウントしたサーバー設定などは更新されますが、コンテナ自体は更新されません。(Dockerfileが更新されていたとしてもそれは利用されない)
コンテナを更新したい場合は下のイメージが更新されたらを参照してください。

イメージが更新されたら

会社によっては専用のdockerイメージがある場合があります。
もしもdockerイメージが更新された場合、以下の手順で取り込むことが出来ます。

$ docker compose down
$ docker compose build --pull サービス名
$ docker compose up -d

立ち上がっているコンテナの中に入りたいとき

立ち上がっているコンテナに入りたい場合はdocker compose execを利用します。

$ docker compose exec サービス名 コマンド
$ docker compose exec php-fpm /bin/bash

立ち上がってるコンテナのログを確認したいとき

ログを確認したい場合はdocker compose logsが利用できます。
基本的には--tailオプションを使って末尾から対象の行数だけ表示してtailして確認するのが一般的です。
ログを確認する方法は色々あって、ログをweb上で確認するためのdozzleというアプリケーションも存在します。

docker compose logs --tail=5 必要であればサービス名

サービス名を書かなかった場合はdocker-composeにかかれているサービスすべてのログが流れます。

コンテナのアプリケーションからDBなどのサービスへ接続したいとき

コンテナ内のアプリケーションからDBなどのサービスに接続したい場合があると思います。
ipを頑張って指定する方法もありますが、これはコンテナが立ち上げ直されると変わってしまうためよくありません。
そういったときにはhost名の部分にサービス名を書きましょう。

例えば下に書いてあるdocker-compose.ymlの例で言うとhost名の部分にmysqlという文字列を設定することでアクセスすることが出来ます。

docker-compose.ymlについてもう少し知りたい

とりあえず、サンプルとしてdocker-compse.ymlを用意しました。
各場所にコメントを入れています。

version: "3.9" # 利用するdocker-compose.ymlのバージョン。バージョンによって書ける項目などが若干異なる
services: # 各サービスの定義
  nginx: # nginxという名前でサービスを定義、これがコンテナになる
    image: nginx:alpine # 取得してくるイメージ。ドメイン名が入ってない場合はDocker Hubのもの。/すら入ってない場合はdockerオフィシャルイメージ。
    volumes: # 共有ボリュームの設定
      - ./:/app # ホスト:コンテナ[:オプション]の順に記述する。
      - ./docker-assets/nginx/default.conf:/etc/nginx/conf.d/default.conf:cached
    ports: # ポートフォワーディングの設定
      - "8080:80" # 順番にホスト側:コンテナ側で書く
      
  php-fpm:
    build: ./docker-assets/php-fpm/ # buildが書かれている場合、ローカルにDockerfileが存在する。対象の場所にDockerfileというファイルがあるので見てみよう
    volumes:
      - ./:/app

  mysql:
    image: mysql:5.7 # :のあとに書かれているのは取得するタグ。イメージにタグが振られている。
    environment: # 環境変数。基本的にはビルド時に使われる。
      MYSQL_DATABASE: ${DB_DATABASE} # ${名前}と書いた場合、.envファイルを探しに行って対象のキーの値を割り当てる
      MYSQL_USER: user # もちろんそのまま文字列も指定できる
      MYSQL_PASSWORD: ${DB_PASSWORD:-passtext} # .envに書かれてなかった場合、passtextという文字列がセットされる
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/mysql # ホストが下に定義されているvolumeの場合もある
volumes: # ボリュームの定義。コンテナが消えても保持しておきたいデータなどがある場合に定義する
  db-data: # db-dataというローカルボリュームを定義している

現在の主流のバージョンは2系または3系です。主に2系を使わなくてはいけない場合としてvolumes_fromでの記述がされている場合です。busybox等で共有を一括して書いているようなサービスがあると3系ではどちらのサービスにもvolumesの指定が必要でした。

その他の設定できる項目については公式をどうぞ。
https://docs.docker.com/compose/compose-file/

ローカルvolumeを消したいとき

まれにローカルボリュームを消したいときがあります。そんなときは-vオプションを利用しましょう。

$ docker compose rm -v サービス名
サービス名を指定しなかったらdocker-compose.ymlに書かれているものすべて消えます

また、基本的にローカルボリュームはプロジェクト名_ボリューム名で作成されます。
なので、

$ docker volume ls

でボリューム一覧を確認して

$ docker volume rm プロジェクト名_ボリューム名

で削除することも可能です。

使用してないコンテナを削除したいとき

stopしているコンテナを削除してくれます。

$ docker container prune

使用してないvolumeを削除したいとき

docker container lsで紐付いてないvolumeをすべて削除できます。

$ docker volume prune

使用してないimageを削除したいとき

上記のvolumeを消したいやつと同じです。

$ docker image prune

使っているネットワークが削除できない時

たまにdocker networkが消せないときがあります

$ docker network rm ネットワーク名

そんなときにはinspectで使われているコンテナを探して落としましょう。

$ docker network inspect ネットワーク名
$ docker down コンテナ名

Discussion

futamintfutamint

場合によってですが、imageがpullされない場合があるのでうまく最新のものが取り込めなかった場合はdocker pull 対象のイメージ名を行ってください。

--pull オプションか --no-cache オプションを使って、イメージの pull を明示的に指示するのも良いかもしれません。

docker-compose build --pull サービス名 
docker-compose build --no-cache サービス名 

docker-composer build リファレンスページ
https://docs.docker.com/compose/reference/build/

at_sushiat_sushi

docker-compose stopというコマンドもありますが、こちらは立ち上げたコンテナを消さないで保持するコマンドです。こっちは基本的に使いません。

すみません、なぜ基本的にstopではなくdownを使用しているかお聞きすることは可能でしょうか?

fagaifagai

stopを使っても良いのですが、清潔に保つという点と途中でdocker-compose.ymlが更新されたときなどに対処できるようにするためというのが大きいかなと思います。
基本的にという書き方が良くなかったと思うので少し書き換えておきます。

at_sushiat_sushi

すみません、追加で質問を失礼いたします。
docker-compose downを使用する目的として、
・清潔に保つ
・クリーンに保つ
という表現をよく見かけるんですが、これの意味について質問です。

例えば、downのかわりにstopを使うとコンテナが残るので、
docker-compose ps -aを実行した時に、今は開発していないプロジェクトのコンテナが残ってる状態かと思います。これが邪魔なので不要なコンテナを削除して開発環境をクリーンに保つという意味なのか、

もしくは、
stopだと何かしら不要なデータがコンテナに蓄積するので、それをクリーンにするためにdownを使うというニュアンスで言っているのか。

どちらでしょうか?

fagaifagai

どちらかというと後者の意図が大きいですねー。

at_sushiat_sushi

ありがとうございます!!
ちょっと調べてもわからなかったので、例えばどんなデータが蓄積するか教えてもらうことは可能でしょうか?

fagaifagai

どんなデータというよりは、コンテナ内でゴニョってるとdownがしにくくなります。
その結果、更新してほしいと言われたときにコンテナを落としにくくなってしまいます。(あとコンテナ自体が何らかの影響で動かなくなる等)
なのでできるだけDockerfileに書いて、downでも大丈夫にしときましょうという意図です。