Docker-composeとは
複数のコンテナからなるサービスを効率的に作成するための設定ファイル、およびそれを実行するためのコマンド。
一つのサービスは複数のコンテナからなる場合がほとんどであり、例えばWordPressでブログを運用する場合にはWordPress用と記事を保管するMySQLようで最低でも2つのコンテナが必要になる。
この場合、本来であれば
- コンテナを収容する
Dockerネットワーク
を作成する。 - WordPressとDockerそれぞれのコンテナを作成する。
- 両者を作成済みのネットワークに追加する。
- WordPressとMySQLで使用する環境変数を設定する。
などの作業が必要になり、その都度ターミナルコマンドを発行することになる。
しかしこの手順をdocker-compose.yml
というファイルに記述して実行することで一連の処理が自動で行われるので、サービスを効率的に構築することができる。
Docker-composeを利用したサービス構築の手順
- Linux用のdocker-composeのインストール
- docker-compose.ymlの作成
- docker-compose.ymlの実行
Linux用のdockercomposeのインストール
windows, macに関してはdocker desktopをインストールした時点でdocker-composeが実行可能になりますが、linuxに関してだけは別途でインストールが必要です。
% sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# curlは指定したurlにアクセスするためのコマンド
# 書式はcurl url -o アウトプットの出力先
# -Lはリダイレクトがある場合にそちらに遷移するためのオプション
# 上記例では、指定したurlもしくはそのリダイレクト先からdocker-composeのファイルをダウンロードして
# /usr/local/bin/docker-composeに保存している
% sudo chmod +x /usr/local/bin/docker-compose
# chmodはコマンドの権限を操作するためのコマンド
# 上記例では全てのユーザーにdocker-composeの実行権限を付与(+x)している
docker-compose.ymlの作成・実行
version: '3.3'
services:
httpd:
image: httpd:2.4.43
ports:
- "80:80"
上記のようにファイルを作成し
% docker-compose up [-d] # -dをつけるとバックグラウンドで実行される
と唱えるとhttpd:2.3.43
というイメージをもとにしたコンテナ(apacheサーバー)が作成され、ホストOSの80番ポートへのアクセスがapacheの80番ポートに転送されるようになる
docker-compose.ymlの解説
docker-compose.ymlとは、ネットワークに所属するコンテナの設定を記述していくためのファイル
。
このファイル内では一つ一つのコンテナをサービスと呼んでおり、
services:
サービス名1:
項目名1:値1
項目名2:値2
項目名3:値3
....
サービス名2:
項目名1:値1
項目名2:値2
項目名3:値3
....
としていくことでネットワーク内に作成するサービスが定義される。
なお、services:とサービス名、サービス名と項目名の間にはそれぞれ半角スペースが必要。
# docker-compose.ymlのフォーマットのバージョン指定
version: '3.3' # 現時点では3.3が安定版とのこと
services:
# この部分に書かれたものがサービスの内容になる
# サービス名の定義
# 分かればなんでも良い
httpd:
# もとにするイメージの指定
image: httpd:2.4.43
# ポート転送の設定
ports:
- "80:80"
このファイルを実行した状態でホストPCからlocalhost/
にアクセスするとIt Works
と表示される(80番ポートにアクセスするとIt Works
と表示されるというのは、apacheのデフォルト設定)。
なお、この際に作成されるネットワーク名は
docker-compose.ymlのディレクトリ名_サービス名_数字
になる。
おまけ〜imageの代わりにDockerfileを指定する
上記の例ではdocker-compose.ymlの中でベースとなるdockerイメージを指定したが、イメージの代わりにDockerfileを指定することも可能。
以下のようにファイルを書き換える(コメントアウトしている部分が削除箇所)。
version: '3.3'
services:
httpd:
# image: httpd:2.4.43
# 以下の2行を追加
build:
context: "Dockerファイルのディレクトリへの相対パス" # 同じディレクトリなら.でOK
ports:
- "80:80"
Dockerfile内でベースイメージを指定しているはずなので、そこを経由してベースイメージの情報が取得される。
おまけその2〜複数のサービスの連携
同一ネットワーク内で複数のサービスを起動させる場合には以下のように記述する。
version: '3'
services:
mysql:
image: mysql:8.0.20
platform: linux/x86_64
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- mysql
image: wordpress:php7.4-apache
platform: linux/x86_64
ports:
- "80:80"
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
以下、個別解説です。
platform: linux/x86_64
dockerイメージはプラットフォームに合わせて複数用意されていることが多く、基本的にはホストOSに合わせたものがダウンロードされる。
しかしdockerイメージの中にはM1Mac対応版(=arm64版)が存在しないものも多い。
そのような場合には以下のようなエラーが出るので、platformとしてlinux/x86_64
版を指定する。
no matching manifest for linux/arm64/v8 in the manifest list entries
x86_64
というのはIntelMac用のバージョンだが、Docker上であれば問題なく動作する。
restart: always
# ホストOSやデーモンの起動時にサーバーが自動で起動される
environment:
変数名: 値
depends_on:
- mysql
mysqlの後にwordpressサービスの作成が開始されるように指定している。
WORDPRESS_DB_HOST: mysql:3306
wordpressのDBホストとして、mysqlサービスの3306番ポートを指定している。
おまけその3〜volumesの作成
上記の例ではDBのデータがコンテナ内に保存されるようになっているが、この方法ではコンテナを削除した際にデータがすべて消えてしまう。
しかし、docker-compose.ymlの中にvolumes
という項目を作成し、そのパスとしてホストOSのディレクトリを指定することでDBの内容をホストOSに保存することができるようになる。
version: '3'
services:
mysql:
image: mysql:8.0.20
platform: linux/x86_64
# 以下の2行を追加
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: wordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- mysql
image: wordpress:php7.4-apache
platform: linux/x86_64
ports:
- "80:80"
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
# 以下の2行を追加
volumes:
db_data:
まず
volumes:
db_data:
でdb_dataという名前のvolumesを作成し
volumes:
- db_data:/var/lib/mysql
でdb_dataというvolumesのパスを指定している。