🗂

docker-composeの環境構築、命令コマンドの使い方について

に公開

docker-compose.ymlは、複数のコンテナを管理・設定するための「設計図」のようなものです。この記事では、私が作成したdocker-compose.ymlの内容を基に、フロントエンド、バックエンド、データベースなどのサービスをどのように連携させているのか、その設定や命令コマンドの学習内容を記録します。

docker-compose.yml全体の概要

docker-compose
version: "3"
services:
  db:
  ...
  backend:
  ...
  frontend:
  ...
volumes:
  ...
  • versiondocker-composeファイルのバージョンを3で指定します。(最新のバージョンを使うことで新しい機能が利用できます。)
  • services:この箇所で、各コンテナ(サービス)の設定を記述します。
  • volumes:データベースコンテナを使っている場合、コンテナ内に保存されたデータを永続化しないと、コンテナを再起動するたびにデータが消えてしまいます。
    volumesを設定すると、データをローカルPCに保存できるため、再起動してもデータを保持します。

各サービスの設定

1. データベース(db)サービス

MySQLを使用したデータベースの設定をします。

docker-compose
  db:
    image: mysql:8.0.34
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: password
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql-data:/var/lib/mysql
    ports:
      - 3307:3306
    platform: linux/x86_64

ポイント

  • image:使用するDockerイメージを指定することができ、データベースではMySQLの公式イメージ(バージョン8.0.34)を使用しています。特定のバージョンを明示することで、意図しないバージョンの更新による不具合を防ぐようにします。
  • restart:コンテナが停止した場合、自動的に再起動する設定をalwaysと指定することで、常に再起動されるようにします。これにより、予期しない停止が発生しても、サービスが自動で復旧します。
  • environment:コンテナ内で使用する環境変数を指定することができ、MYSQL_ROOT_PASSWORDを設定することで、MySQLのルートユーザー(root)のパスワードをpasswordにします。これにより、MySQLに接続する際の認証情報を指定します。
  • command
    コンテナが起動するときに実行するコマンドです。
    • --default-authentication-plugin使って、MySQLの認証方式をmysql_native_passwordに設定します。
    • mysql_native_passwordにより、MySQL 8.0以前と同じ認証方式を使えるため、古いクライアントやアプリケーションでも接続できるようになります(MySQL 8.0以降のデフォルトではcaching_sha2_passwordとします)。
  • volumes:コンテナ内のデータフォルダ(/var/lib/mysql)をローカルPCに保存します。この設定により、コンテナを削除してもデータは残り、いつでも使い続けられます。
  • ports:ローカルPCのポート3307をコンテナ内のポート3306につなげています。これで、ローカルPCのlocalhost:3307にアクセスすると、コンテナ内のMySQL(ポート3306)に接続します。
  • platform:コンテナをLinuxのx86_64アーキテクチャで動かすように指定しています。この設定を使うと、ローカルPCが異なるアーキテクチャ(例えばM1 Macなど)でも、問題なくコンテナを動作させることができます。
    ※ MySQLの公式イメージはx86_64用に最適化されているため、この設定で互換性を確保します。

2. バックエンド(backend)サービス

Railsのバックエンドを動かすための設定をします。

docker-compose
  backend:
    build:
      context: ./backend/
      dockerfile: Dockerfile
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ./backend:/myapp
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
      # DB_HOST: db
      DB_USER: root
      # MYSQL_ROOT_PASSWORD:
    ports:
      - "3001:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true

ポイント

  • build
    バックエンド用のDockerfileを使ってイメージを構築します。
    • context:ビルド対象となるディレクトリで、./backend/ディレクトリを指定します。
    • dockerfile:ビルドで使用するDockerfileをcontext内にあるDockerfileを使用します。なお、名前や場所が異なる場合にこの指定が必要です。
  • command
    コンテナ起動時に実行するコマンドを指定します。
    • Railsサーバーの起動:bundle exec rails s -p 3000 -b '0.0.0.0'で、ポート3000を使用してRailsサーバーを起動し、全てのネットワークインターフェースからの接続を受け付けるようにします。
    • commandで指定したコマンドは、ENTRYPOINTスクリプトの"$@"に引数として渡され、exec "$@"で実行します。
      command: bundle exec rails s -p 3000 -b '0.0.0.0'"$@"に展開され、次のように実行されます
      exec bundle exec rails s -p 3000 -b '0.0.0.0'
      
  • volumes
    ローカルPCの./backendディレクトリを、コンテナ内の/myappディレクトリに保存します。この設定は、ローカルPCでファイルを変更すると、コンテナを再起動や再ビルドすることなく、その内容がリアルタイムでコンテナ内に反映されるようになります。開発中にコードの修正をすぐに確認できるようにするための設定をします。
  • environment
    コンテナの設定を調整するための環境変数を指定します。
    • TZ:タイムゾーンをAsia/Tokyoに設定して、日本時間で動作するようにします。
    • RAILS_ENV:Railsを開発モード(development)で動かし、開発用のエラー画面が表示されるなど、開発しやすい設定にします。
  • ports
    ローカルPCのポート3001を、コンテナ内のポート3000に設定することで、ローカルPCからlocalhost:3001にアクセスすると、コンテナ内のRailsサーバー(ポート3000)に接続します。
  • depends_on
    backendを起動する前に、db(データベース)が先に起動するように指定しています。バックエンドがデータベースと正しく連携できるようにします。
  • stdin_open, tty
    コンテナで対話型ターミナルを有効にする設定です。この設定により、コンテナ内でターミナルを使って直接コマンドを入力したり、デバッグを行うことが可能にします。

3. フロントエンド(frontend)サービス

Vue.jsのフロントエンドを動かすための設定をします。

docker-compose
  frontend:
    build: 
      context: ./frontend/
      dockerfile: Dockerfile
    volumes:
      - ./frontend:/frontend
    command: yarn run serve
    ports:
      - 81:8080
    depends_on:
      - backend
    stdin_open: true
    tty: true

ポイント

  • build
    フロントエンド用のDockerfileを使って、イメージを構築します。
    • context:ビルド対象となるディレクトリで、./frontend/ディレクトリを指定します。
    • dockerfile:ビルドで使用するDockerfileをcontext内にあるDockerfileを使用します。なお、名前や場所が異なる場合にこの指定をします。
  • volumes
    ローカルPCの./frontendディレクトリを、コンテナ内の/frontendディレクトリに保存します。この設定は、ローカルPCでファイルを変更すると、コンテナを再起動や再ビルドすることなく、その内容がリアルタイムでコンテナ内に反映されるようになります。開発中にコードの修正をすぐに確認できるようにするための設定をします。
  • command:
    • yarn run serveを実行して、フロントエンドの開発サーバーを起動します。この設定で、コンテナを立ち上げるとフロントエンドのアプリをブラウザで確認できるようにします。
    • フロントエンドにはENTRYPOINTを使用していないため、commandがそのままコンテナの起動時に実行されるコマンドとして使用します。
  • ports
    ローカルPCのポート81を、コンテナ内のポート8080に設定することで、ローカルPCからlocalhost:81にアクセスすると、コンテナ内で動作する開発サーバー(ポート8080)に接続します。
  • depends_on
    frontendを起動する前に、backend(バックエンド)が先に起動するように指定しています。フロントエンドがバックエンドと正しく連携できるようにします。
  • stdin_open, tty
    コンテナで対話型ターミナルを有効にする設定です。この設定により、コンテナ内でターミナルを使って直接コマンドを入力したり、デバッグを行うことが可能にします。

Volumesの設定

docker-compose
volumes:
  mysql-data:

ポイント

  • volumes:
    mysql-dataは、データベースのデータを保存するためのボリュームです。この設定により、データがローカルPCのDockerボリューム領域に保存されるため、コンテナを削除してもデータが失われません。

docker-composeに登場する命令コマンドの解説

docker-composeを構成する命令コマンドの役割を、簡単にまとめてみました。
使い方や注意点も参考にしてください。

  • version:Composeファイルのバージョンを指定します。
    バージョンによって記述方法が異なります。CircleCIなどのCIツールでは2系以上を推奨します。
  • services:コンテナの設定情報を定義します。
    各サービス(例:frontendbackend)ごとに設定を記述します。
  • image:使用するDockerイメージを指定します。
    既存のDockerイメージを使う場合はimage、カスタムビルドする場合はbuildを使用します。
  • build:Dockerfileをビルドする際のディレクトリや設定を指定します。
    環境変数をargsオプションでDockerfileに渡すことが可能です。
  • volumes:コンテナ内のデータをローカルpcに保存するための設定をします。
    ホスト側ディレクトリとコンテナ側ディレクトリをリアルタイムでリンクし、データ永続化や開発効率向上を可能にします。
  • environment:コンテナ内で使用する環境変数を定義します。
    env_fileを使用して外部ファイルから環境変数を読み込むことも可能にします。
  • command:DockerfileのCMDを上書きし、コンテナ起動時に実行するコマンドを指定します。
    例:rails serverを起動する設定など。
  • ports:ホストとコンテナのポートを保存します。
    例:3001:3000の形式で指定します。数値を文字列で指定することでYAMLパースエラーを防ぐようにします。
  • platform:コンテナの動作環境(アーキテクチャ)を指定します。
    例:M1 Macではlinux/arm64、MySQL公式イメージではlinux/amd64を推奨します。
  • depends_on:サービス間の依存関係を指定します。
    指定した順序でサービスが起動します。例:frontendbackendから起動します
  • stdin_open:コンテナの標準入力を有効にし、対話型操作を可能にします。
    例:rails consolepryのようなデバッグツールで入力を受け付けるために使用します。
  • tty:コンテナの標準出力をホストマシンに接続します。
    コンテナ内での出力をホストで確認できるようになり、デバッグがしやすくします。

今回の記事では、docker-compose.ymlを活用して、複数のサービスを連携させる方法を紹介しました。この記事を参考に、自分のプロジェクトに合った設定をカスタマイズして、効率的な開発環境を構築してみてください!

Dockerfile:「Dockerfileのフロントエンドとバックエンドの構築、命令コマンドの使い方について」も参考にして下さい!

Discussion