docker-composeを利用すると複数のコンテナをdocker-compose.ymlで作成できます。
docker-composeのインストール
docker-composeはdockerとは別にインストールする必要があります。
pipやパッケージツール(apt)から入れるほかリポジトリからも入れられます。
# curl -L https://github.com/docker/compose/releases/download/1.29.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
docker-composeのバージョン確認
# docker-compose --version
最新バージョンはリリースページから確認してください。
上のコマンドでうまく入れられない場合はリリースページからお使いのPCにあったバージョンをインストールします。
docker-composeとは?
docker-composeはイメージのダウンロードから、ネットワークやボリュームの作成などを行い、コンテナを作成するまでを行います。docker-compseでは対話式のコマンド入力ではなく、docker-composeファイルを読み込んで作成します。
docker-composeは単にdockerコマンドで入力する内容を文書化したものにすぎないので、docker-composeを使わずとも、dockerコマンドの手入力で同じことができます。
コンテナ構成をコード化する ” Infrastracture as code:IaC”の観点では重要なツールです。
手入力ではミスしやすく、複雑ですが、docker-compose化すればこれを実行するだけで同じものがコンテナ環境を構築でき、複数のコンテナをまとめて起動・停止・削除することができて便利です。
※dokcerfileはカスタムイメージを作成するツールでコンテナの構築は範囲外で別物
オリジナルなカスタムイメージを作成→プルして起動すればそのまま使えるというような感じでカスタムするポイントがちょっと違う。
docker-composeコマンド
docker-composeコマンドはdockerコマンドと共通点が多く似ています。
- dcoker-compose ${variable} docker-compose.yml
- up コンテナの作成・起動・再起動
- down コンテナの停止・image,networkの削除 -vでボリュームも削除
- start 止まってるコンテナの起動
- stop コンテナの停止
- run 特定のserviceのコンテナを指定して起動する
- サービス名の指定が必要で依存関係のコンテナも起動。testやデータの追加といった一時的な用途に利用。-itが内包されており、インタラクティブシェルが起動する。
- create コンテナの作成
- 非推奨: docker-compose up –no-startを代わりに使う(サービスの作成だけで起動しない)
- build イメージの構築
- kill コンテナの強制停止
- restart 停止or実行中のサービスを再起動する
- rm 停止中のサービス・コンテナを削除, volumeは削除しない
- scale 指定した数のコンテナを実行する
- 非推奨, up –scaleオプションで利用する
- exec 指定したサービス内でコマンドを実行する
- ps コンテナの一覧を表示する
- port 指定したサービス中のコンテナが使用中のポートがバインドしてるホストのポート
- 詳細は※コマンド挙動詳細
- images コンテナが使っているimageを表示
- pause 起動中コンテナ一時停止する
- unpause 一時停止を解除する
- logs サービスからのログ出力を表示
- top 実行中のプロセスを表示
https://docs.docker.jp/engine/reference/commandline/compose_start.html
※docker-composeでは複数のコンテナを扱うことが多く、サービスという単位でコンテナを管理する
docker-compose stop
コンテナにSIGTERMを送信、10秒経ってタイムアウトしたらSIGKILLを送信する。
docker-compose port ${サービス中のコンテナ名} コンテナのポート番号
docker-compose.ymlを見ればわかることだが、docker-compose portコマンドで確認してみる
##---サービス中のコンテナ名がwordpressであることを確認
# docker-compose ls
NAME STATUS CONFIG FILES
wordpress restarting(1), running(1) /root/develop/docker/wordpress/docker-compose.yml
##---コンテナの中の使用ポートを確認する→80番ポート
# docker-compose exec -it wordpress netstat -ltnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.11:35731 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/apache2
##---コンテナ80ポートがホストのどのポートにバインドしてるかを確認する→8000番
# docker-compose port wordpress 80
0.0.0.0:8000
##---ホストの8000番を確認する
# netstat -ltnp | grep 8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 3058535/docker-prox
tcp6 0 0 :::8000 :::* LISTEN 3058543/docker-prox
##---PIDからプロセスの詳細argを確認する→コンテナのport80と逆引きできる
# ps wwlp 3058535
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
4 0 3058535 928 20 0 1296064 3224 futex_ Sl ? 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8000 -container-ip 172.19.0.3 -container-port 80
docker-compose.ymlの作成
docker-compose.ymlというファイルを作成します。(新しいバージョンv2ではcompose.ymlが優先される)
yml形式でコンテナの構成(ボリュームとかネットワーク)を記述し、これを読み込んでコンテナを起動します。※.jsonを指定してJSONを利用できる
wordpressをdocker-composeで構築する
wordpressはwebサーバとDBサーバなど複数のサーバが必要なのでdocker-composeの例として適しています。
チュートリアルが公式にあります。https://docs.docker.jp/compose/wordpress.html
1.docker-compose.ymlを作成する
version: '3'
services:
db:
image: mysql:5.7
platform: linux/amd64
#platformはM1 MacなどCPUがarmの場合にエミュレートのため追加
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
serviceとVolumesの2つの項目がある。
serviceには2つのコンテナの設定、volumesにはdbコンテナに接続するボリュームdb_dataが記載
2.docker-compose.ymlを使ってサービスを起動する
$ ls
docker-compose.yml
$ docker-compose up -d
3. コンテナに入って確認する
起動後にdocker psで確認すると2つのコンテナが起動している。
wordpressのコンテナはapache2が起動している。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
392c4a301212 wordpress:latest "docker-entrypoint.s…" 16 seconds ago Up 15 seconds 0.0.0.0:8000->80/tcp wordpress-wordpress-1
e1c45e2ea61b mysql:5.7 "docker-entrypoint.s…" 16 seconds ago Up 15 seconds 3306/tcp, 33060/tcp wordpress-db-1
$ docker exec -it wordpress-wordpress-1 /bin/bash
# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.8 230360 34184 ? Ss 16:35 0:00 apache2 -DFOREGROUND
www-data 57 0.0 0.2 230400 9792 ? S 16:35 0:00 apache2 -DFOREGROUND
www-data 58 0.0 0.2 230400 9792 ? S 16:35 0:00 apache2 -DFOREGROUND
www-data 59 0.0 0.2 230400 9792 ? S 16:35 0:00 apache2 -DFOREGROUND
www-data 60 0.0 0.2 230400 9792 ? S 16:35 0:00 apache2 -DFOREGROUND
www-data 61 0.0 0.2 230400 9792 ? S 16:35 0:00 apache2 -DFOREGROUND
root 62 0.1 0.0 3956 3176 pts/0 Ss 16:36 0:00 /bin/bash
root 322 0.0 0.0 6444 2432 pts/0 R+ 16:37 0:00 ps aux
docker-compose.ymlで指定したimage: wordpress:latestはapacheの名前は書いていなかった。
imageの詳細を確認してみる
$ docker images | grep wordpress
wordpress latest 4a205c51d398 5 days ago 567MB
$ docker inspect wordpress
##exposePortsで80番を指定したり、php, apacheの設定が確認できる
"ExposedPorts": {
"80/tcp": {}
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"PHPIZE_DEPS=autoconf \t\tdpkg-dev \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkg-config \t\tre2c",
"PHP_INI_DIR=/usr/local/etc/php",
"APACHE_CONFDIR=/etc/apache2",
"APACHE_ENVVARS=/etc/apache2/envvars",
"PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64",
"PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64",
"PHP_LDFLAGS=-Wl,-O1 -pie",
"GPG_KEYS=1729F83938DA44E27BA0F4D3DBDB397470D12172 BFDDD28642824F8118EF77909B67A5C12229118F 2C16C765DBE54A088
130F1BC4B9B5F600B55F3B4",
"PHP_VERSION=8.0.27",
"PHP_URL=https://www.php.net/distributions/php-8.0.27.tar.xz",
"PHP_ASC_URL=https://www.php.net/distributions/php-8.0.27.tar.xz.asc",
"PHP_SHA256=f942cbfe2f7bacbb8039fb79bbec41c76ea779ac5c8157f21e1e0c1b28a5fc3a"
],
4.wordpressのURLに接続する
docker-compose.ymlから、コンテナの80ポートがホストの8000にバインドしているのでローカルホストの8000にアクセスする
http://127.0.0.1:8000
mysqlは32bit版のイメージが公式にはないので、mariadbのイメージを使う。完全に動作するか?は確かめていないが起動は確認している
version: '3'
services:
db:
#image: mysql:5.7
image: mariadb
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
volumes:
db_data:
実際に設定を進めていくとwordpressがインストールされてブログページが作成できるのが確認できます。
使い終わったら
docker-compose.ymlのあるディレクトリでdocker-compose downとすればOK
ボリュームは別途削除するか、一緒に削除したい場合は-vをつける。
2つの項目
services
サービスには稼働させるコンテナ名と詳細を書きます。
下記の例では、dbとwordpressの2つのコンテナからサービスが成り立っています。
services:
db:
image: mysql:5.7
platform: linux/amd64
#platformはM1 MacなどCPUがarmの場合にエミュレートのため追加
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
wordpress:
depends_on:
- db
image: wordpress:latest
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
残りの項目について
- image → どのイメージを使うか?
- volumes →データ永続のためdockerボリュームを使用する場合はそのボリューム名を書く
- volumesをserviceに書いた場合はvolume作成ようにvolumesの大項目を別途記載する必要あり
- ports →ポートのマップ情報を書く ホストポート:コンテナポート
- restart 起動時にコンテナが停止した場合に常に再起動リトライする場合は “always”を指定
- environment →環境変数を設定
- depens on 指定したコンテナの後に起動するように依存関係を記述
Volumes
作成するdockerボリューム名を書く
volumes:
db_data:
残りの項目
version
versionは3.xと書いてることが多いです。現在の最新はversionを記載するのではなく、コンポーズ仕様という書式に則って記載することで、versionの記載は不要になりました。
https://docs.docker.jp/compose/compose-file/compose-versioning.html