Dockerでなにかのシステムを構築する場合、通常はdockerコマンドを駆使して行います。
システムには、ご存知の通り、Webサーバなどのように1つのサービスを作れば良いものから、アプリケーションサーバのように複数のサービスを組み合わせる必要のあるものまで様々な形態があります。
Dockerコンテナひとつだけのシステムでしたらdockerコマンドで十分だと思いますが、複数のDockerコンテナが組み合わさったシステムの構築は、dockerコマンドだけですと結構大変です。
そんなときはdocker-composeコマンドをおすすめします。
docker-composeを使えば、複数のDockerコンテナをコマンドひとつで作れたり、起動や停止、再起動なども簡単に行うことができます。
本記事では、dockerコマンドと比較しながら、実際にサービスを構築する例をまじえてdocker-composeの使い方を解説してます。
そのために、まず最初にdockerコマンドのみでの構築方法について説明しまして、その後で同じサービスをdocker-composeで構築する方法について解説します。
2つの方法の違いを体感していただければ幸いです。
docker-composeのインストール
解説用のシステムの構築を始める前に、docker-composeのインストール方法について解説します。
方法は、Docker公式サイト上に存在するdocker-composeのバイナリ(OS単位に別ファイル)をダウンロードして、パスの通った場所にファイル名「docker-compose」として保存するだけです。
本ページで使用するDockerはLinux版ですので、docker-composeのLinux版についてご紹介させていただきます。
rootにて以下のコマンドを実行します。<xx.xx.xx>の部分は、docker-composeのバージョンになります。
※2024.2時点の最新版は「2.24.5」
# curl -L https://github.com/docker/compose/releases/download/v<xx.xx.xx>/docker-compose-`uname -s`-`uname -m` > /usr/bin/docker-compose
# chmod 755 /usr/bin/docker-compose
docker-composeの最新版や入手方法は以下のサイトでご確認ください。
以下のコマンドでdocker-composeのバージョンを確認できます。
# docker-compose -v
構築するシステムについて
解説するために構築するシステムの構成概要を下図に示します。DockerはLinux(Ubuntu18.04)版の19.03.10を使用します。
システムは簡易的な3層アプリケーションサーバで、Webコンテナ(web01)とDBコンテナ(db01)の2コンテナ構成とします。
Docker内に、サービス専用のdockerネットワーク(test-net01)を作成します。DBコンテナのポートには外部からは直接アクセスできません。
また、各々のDockerコンテナにマウントするデータボリュームを作成します。
dockerコマンドによるシステム構築
まずは、dockerコマンドのみでの構築方法を解説します。
データボリュームの作成
2つのDockerコンテナにマウントするデータボリュームを作成します。
作成したデータボリュームは、Dockerコンテナの起動時に「-v」オプションで指定することになります。
Webコンテナ用の2つのデータボリュームを作成します。
$ docker volume create --name web01_doc
web01_doc
$ docker volume create --name web01_log
web01_log
作成されているか確認します。
$ docker volume ls | grep web01
local web01_doc
local web01_log
次に、同じようにDBコンテナ用の2つのデータボリュームを作成します。
$ docker volume create --name db01_data
db01_data
作成されたか確認します。
$ docker volume ls | grep db01
local db01_data
Dockerネットワークの作成
サービス専用のDockerネットワークを作成します。
作成したネットワークは、Dockerコンテナの起動時に「--net」オプションで指定することになります。
$ docker network create -d bridge test-net01
69bfaf47b1e6640a872fd43c3851d117d8bb4b94fbe4b5839de39bf23a950111
「-d」オプションに「bridge」と設定することで、Dockerホスト外と通信が可能になります。
作成されているか確認します。
$ docker network ls | grep test-net01
69bfaf47b1e6 test-net01 bridge local
DBコンテナの起動
基本的に、DBサーバはWebサーバが起動する時点で、既に起動されていた方が良いと思います。
よって、最初はDBサーバから起動します。
ベースイメージはMariaDBの公式Dockerイメージ(現時点の最新版)を使用します。
$ docker run -d --net test-net01 -v db-1_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=testtest --name db01 mariadb:latest
※青字部分は、最初にご覧いただきました今回構築するシステムの図内で定義した値になります。
※「MYSQL_ROOT_PASSWORD」に設定しているtesttestはMariaDBのrootユーザの初期パスワードになります。ご自分のお好きな文字列を指定してください。
「docker ps」コマンドで起動確認を行います。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d96be66a4ad6 mariadb:latest "docker-entrypoint.sh" About a minute ago Up About a minute 3306/tcp elated_swirles
DBコンテナの初期設定
DBコンテナが起動しましたら、DBサーバであるMariaDBの設定を行います。
設定内容や方法につきましては、Docker固有のものではないために本記事では省略させていただきます。
Webコンテナの起動
次にwebコンテナを起動します。
ベースイメージはPHPの公式Dockerイメージ(現時点の最新版)のapache同梱版を使用します。
$ docker run -d --net test-net01 -p 8080:80 -v web_doc:/var/www/html -v web_log:/var/log/apache2 --name web01 php:7-apache
「docker ps」コマンドで起動確認を行います。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81a01a55b5bc php:7-apache "apache2-foreground" 23 hours ago Up 3 seconds 0.0.0.0:8080->80/tcp web01
Webコンテナの初期設定
Webコンテナが起動しましたら、WebサーバであるApacheの設定を行います。
設定内容や方法につきましては、Docker固有のものではないために本記事では省略させていただきます。
以上が、WebサーバとDBサーバの2つのDockerコンテナをdockerコマンドで作成する内容になります。
docker-composeコマンドによるシステム構築
次に、同じ内容をdocker-composeコマンドを使用して行います。
(注意)
8080番ポートが被るので、前章で解説しました「dockerコマンドのみの作業」にて起動した2つのDockerコンテナを作成された方は、「docker stop」コマンドで2つとも停止してください。
docker-compose.ymlファイルの作成
Dockerホストに作業ディレクトリ(ディレクトリ名はex2)を作成しまして、そこに以下の内容のdocker-compose.ymlファイルを作成します。
version: "2"
services:
web01:
image: php:7-apache
volumes:
- web01_doc:/var/www/html
- web01_log:/var/log/apache2
ports:
- "8080:80"
depends_on:
- db01
db01:
image: mariadb
volumes:
- db01_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: testtest
volumes:
web01_doc:
web01_log:
db01_data:
dockerコマンドのみで行う際には、事前にコマンドでデータボリュームを作成したり、起動時に多くのオプションを指定したりしましたが、docker-composeコマンドを使用する場合は、それらをdocker-compose.ymlファイルに既定のフォーマットに従って記述するだけ大丈夫です。
設定内容について簡単に説明します。
「service:」と「volumes:」のキーワードが記述されてますが、「service:」はDockerコンテナに関する定義情報、「volumes:」はデータボリュームの定義情報を記述します。
Dockerネットワークについての記述が見当たりませんが、ネットワークの設定が無い場合は、デフォルトで1回のdocker-composeコマンドの実行で作成されるDockerコンテナ群に1つの専用のDockerネットワークが作成され、定義されたDockerコンテナ群の全てがそのネットワークに属します。
「service:」内の「web01」の定義内に「depends_on」とありますが、これは、web01はdb01にdepends_on(頼る)する、つまり、web01はdb01が起動してから起動されます。
Dockerコンテナ間の依存関係の定義が可能です。
サービスの起動
「docker-compose.yml」ファイルが作成できましたら、作業ディレクトリ上で以下のコマンドを実行してください。
$ docker-compose up -d
Creating network "ex2_default" with the default driver
Creating volume "ex2_web01_log" with default driver
Creating volume "ex2_db01_data" with default driver
Creating volume "ex2_web01_doc" with default driver
Creating ex2_db01_1
Creating ex2_web01_1
カレントディレクトリ内の「docker-compose.yml」が読み込まれて、記述内容通りにシステムが起動します。
実行後の出力内容より、このコマンド1つで、以下のものが作成されました。
- Dockerネットワーク ex2_default(test-net01に該当)
- データボリューム ex2_web01_log(web01_logに該当)、ex2_db01_data(db01_dataに該当)、ex2_db01_data(db01_dataに該当)
- Dockerコンテナ ex2_db01_1(db01に該当)、ex2_web01_1(web01に該当)
先ほどは、dockerコマンドで1つ1つ作成したものが、docker-composeコマンド1発で作成されました。
以下のコマンドで起動確認を行って下さい。
$ docker-compose ps
Name Command State Ports
------------------------------------------------------------------------
ex2_db01_1 docker-entrypoint.sh mysqld Up 3306/tcp
ex2_web01_1 apache2-foreground Up 0.0.0.0:8080->80/tcp
Dockerコンテナが2つ起動されているのが確認できます。
dockerコマンドで起動した場合と名前は異なりますが、WebコンテナとDBコンテナが起動されてます。
次は、データボリュームの確認です。
$ docker volume ls | grep 01
local ex2_db01_data
local ex2_web01_doc
local ex2_web01_log
Dockerネットワークの確認です。
$ docker network ls | grep default
97778683a2f5 ex2_default bridge local
必要なものは全て作成されていることが確認できました。
データベースの初期設定
DBサーバであるMariaDBの設定内容や方法につきましては、Docker固有のものではないために本記事では省略させていただきます。
Webコンテナの初期設定
WebサーバであるApacheの設定内容や方法につきましては、Docker固有のものではないために本記事では省略させていただきます。
まとめ
dockerコマンドのみの作業は、全ての部品を自作して、それらをつなぎ合わせるということを全て自分で行う必要があります。
システムの規模が大きくなると、ミスも発生しやすくなりますね。
docker-composeを利用すると、構築したいシステムを設計して、その最終イメージをdocker-compose.ymlに記述して読み込ませるだけで、作業の大部分は終わってしまいます。
それに、docker-compose.ymlは、YAML形式という汎用的なフォーマットを採用しており、とても見やすく、理解しやすいと思います。
今回は、docker-composeの便利さを少しでも体感していただきたくて、記事を書かせていただきました。
本記事の内容は、docker-composeの基本的な内容です。もっともっと素晴らしい機能が実装されておりますので、色々調べてご利用いただければと思います。
尚、本記事は、dockerコマンドを否定するものでは決してありません。この記事を書いてますが、私はdockerコマンドを使う頻度のほうが圧倒的に高いです。
適材適所が重要だと思います。
最後までお読みいただきありがとうございました!
コメント