docker-compose.ymlファイルの解析をする

Docker

docker関係はあまり詳しく深入りせずにやっていましたが、仕事でdockerを使うことが多く、エラーが頻繁に出て対応に追われることが多いので、基礎固めとして、docker-compose.ymlの中身の解析をしていきます。

下記公式ドキュメントを参考に進めています。

Compose ファイル構築リファレンス — Docker-docs-ja 20.10 ドキュメント

今回解析するdocker-compose.ymlファイル

今回解析するのは、dbをmysql、フロントエンドにvue、バックエンドにrailsを使用する想定のdocker-compose.ymlファイルです。

version: "3"
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myqpp_development
      MYSQL_USER: root
      MYSQL_PASSWORD: password
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
      - /tmp/dockerdir:/etc/mysql/conf.d/
    ports:
      - 3306:3306
  api:
    build:
      context: ./backend
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - "./backend:/myapp"
      - ./vendor/bundle:/myapp/vendor/bundle
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - "8000:8000"
    depends_on:
      - db
  app:
    build:
      context: ./frontend
    volumes:
      - "./frontend:/myapp"
      - node_modules:/app/node_modules
    ports:
      - "8080:8080"
    command: npm run serve

volumes:
  mysql-data:

yamlファイルの解析ではservice配下のコンテナ化したいサービスについて説明していきます。それ以外の部分については先に説明しておきます。

  • versionについては基本的に3になることが多いので、おまじない的に3と書いておけばいいみたいです。
  • servicesにはコンテナ化したいものをネスト形式で記載します(今回で言うと、db,api,appの3つのサービスがあり、コンテナは3つ作成されます。)
  • 最後のプログラムであるvolumes: mysql-data:はdocker-volumeと呼ばれ、dockerのvolumeを作成することができるコマンドです。
  • また、yamlファイルの基本構造についてkey:valueのハッシュ構造になっているため、前提知識として、それだけ覚えておくといいと思います。

それではyamlファイルの説明に入っていきます。

db(mysql)のdocker-compose.ymlの解析

image: mysql:8.0            

ベースのイメージとして、mysql:8.0を指定します。これで、dockerhubにあるmysqlイメージを使用することができます。

environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myqpp_development
      MYSQL_USER: root
      MYSQL_PASSWORD: password

環境変数を指定しております。ここで定義しておくことで、dockerコンテナ内で上記の環境変数が使用できるようになります。

command: --default-authentication-plugin=mysql_native_password

commandは、コンテナ作成時に実行されるコマンドです。MYSQLのデフォルトの認証プラグインを設定するためのものです。今回は、mysql_native_passwordに設定しています。

volumes:
      - mysql-data:/var/lib/mysql
      - /tmp/dockerdir:/etc/mysql/conf.d/

続いて、volumesはファイルシステムをホストからコンテナにマウントする際に使用します。volumesの書き方としては、<host側のパス>:<container側のパス>となっており、ホスト側の指定したパスのファイル全てをコンテナ側へとマウントします。こうすることで、コンテナを削除しても、ホスト側へ保存されているため、コンテナ作成時にデータを復元することができます。

プログラムの、一つ目の処理では、host側のmysql-dataは、コンテナ内の/var/lib/mysqlにマウントされ、二つ目では/tmp/dockerdirはコンテナ内の/etc/mysql/conf.d/にマウントされます。

ただし、この2つには違いがあり、一つ目の書き方はボリュームマウントという方法で、二つ目の書き方はバインドマウントと呼ばれる方法をとっています。ボリュームマウントとは、コンテナを落としてもデータを保持し続けるために、ボリュームを別で持つ方法です。

詳しく説明すると、コンテナ内の/var/lib/mysqlのデータ(データが入っているところ)とmysql-dataという外部ボリュームを紐づけています。この2つはマウント関係にあるため、/var/lib/mysqlが更新されるたびにmysql-dataも更新されます。

docker-compose.ymlの最後の行に、volumes:~の記述がありますが、ボリュームマウントを使用する際は、下記のような記載をする必要があります。

services:
  ...

volumes:
  postgres_data

バインドマウントとは、ホストファイルとコンテナ内のファイルをマウントする動作をします。これにより、ローカルでコード変更した内容がコンテナ内のアプリにも反映させることができ、最新の状態に更新する際に、いちいちコンテナを立ち上げ直さなくてもすみます。

ports:
      - 3306:3306

ホストのポートとコンテナのポートを接続しています。<ホストのport>:<コンテナのport>

backend(rails)のdocker-compose.ymlの解析

services:apiの部分の説明になります。

build:
  context: ./backend
  dockerfile: Dockerfile

最初のbuildでは、dockerイメージをとってくる場所を指定するために使用します。contextでは、Dockerfileを含むディレクトリのパスか、gitリポジトリのurlを定義します。今回は、

|_ backend
|          |_Dockerfile
|_docker-compose.yml

このようなディレクトリ構造となっているため、./backendとなっております。

Dockerfileではなく、dbで設定したように直接Dockerイメージを持ってくることもできます。どちらの場合にせよ、ベースのイメージは必要になるため、buildかimageは設定しなければならないと覚えておけばいいと思います。

command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

つづいて、commandの部分。先ほども説明した通り、commandはコンテナ作成時に実行される処理で、backendコンテナ立ち上げ時には2つの処理を実施しています。

“bash -c”ではBashシェルに対してコマンドを送ることができます。ちなみに-cはcommandの略でシェルに対して実行したいコマンドを文字列として渡すことができます。それにより、-c移行の処理はシェルを起動せずに実行することが可能となります。

tmp/pids/server.pid の処理は、pidファイルを削除します。このpidファイルとは、前回のアプリケーション起動時に生成されたPIDファイルです。

続いて、bundle exec rails s -p 3000 -b '0.0.0.0' を実行します。これは、Railsアプリケーションをポート(-p)番号3000で起動し、0.0.0.0のIPアドレスで外部からの接続を許可します。

volumes:
      - "./backend:/myapp"
      - ./vendor/bundle:/myapp/vendor/bundle

volumesもdbと同様、ファイルシステムをホストからコンテナにマウントする際に使用します。<host側のパス>:<container側のパス>となっており、

./backend:/myappでは、hostのbackend内のディレクトリをコンテナ内のmyappへ

二つ目の処理ではホストの./vendor/bundleを/myapp/vendor/bundleへとマウントしています。

environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development

dbと同じように、環境変数を定義しています。

ports:
      - "8000:8000"

ホストのポートとコンテナのポートを接続しています。<ホストのport>:<コンテナのport>

depends_on:
      - db

depends_onが設定されているテナント(api)は、depends_onで指定したサービス(dbコンテナ)が作成された後に作成するよ!という意味を持ったコマンドになります。

今回のようなapiのサービスがdbを参照するようなサービスのときは、参照先のサービスを作っておかないと動かないため、先に作っておく必要があります。

frontend(vue)のdocker-compose.ymlの解析

build:
  context: ./frontend

こちらは、backendの内容と同じで、docker-compose.ymlファイルがあるディレクトリのフロントエンド配下にあるdockerfileを読み込む処理になります。backendと違うのは、dockerfile:の指定がないと言うところです。dockerfileを書かなくても、そのディレクトリから勝手にDockerfileを探して読み込んでくれるみたいですね。

volumes:
      - "./frontend:/myapp"
      - node_modules:/myapp/node_modules

volumesもdb,backendと同様、ファイルシステムをホストからコンテナにマウントする際に使用します。<host側のパス>:<container側のパス>となっており、

./frontend:/myappでは、hostのfrontend内のディレクトリをコンテナ内のmyappへ

2つ目の処理ではホストのnode_modulesをmyapp/node_modulesへとマウントしています。

ports:
      - "8080:8080"

ホストのポートとコンテナのポートを接続しています。<ホストのport>:<コンテナのport>

command: npm run serve

Vue.jsのプロジェクトの開発サーバーを起動するコマンドです。

まとめ

以上、docker-compose.ymlのファイルの解析をしました。

volumeのマウントだったり、commandの実行だったり今まで分からない部分を知ることができました。ymlファイルに書かれている内容を理解した上で今後は使用していこうと思います。

コメント

タイトルとURLをコピーしました