対象の読者について
コンテナ初心者向けとなります。
自分も今、コンテナを学習している初心者です。
書くこととその理由
WordPressをDocker Composeで超簡単に構築できますが、なにがどのように構築されているのかさっぱりわかりませんでした。
この記事では、WordPressをコンテナで構築するとき、Docker Composeを使う場合と使わない場合(ひとつひとつ手作業で行った場合)の、行われていることを詳しく見ていきたいと思います。
その中で、Dockerの基本的なコマンドやネットワークの作成、そしてボリュームのマウントについて見ていきたいと思います。
事前準備
環境と前提をお伝えします。
環境
本記事の環境は以下のとおりとなっております。
項目 | バージョン |
---|---|
OS | CentOS 7 |
Docker | 23.0.1 |
Docker Compose | 2.4.1 |
前提
Docker EngineとDocker Composeはインストール済みの前提で話を進めます。
(補足)Docker EngineとDocker Composeのインストール(CentOS)
CentOS 7において行った、Docker EngineとDocker Composeのインストール手順を、コマンドベースで簡単にメモしておきます。
※ネット上にインストール方法が複数掲載されていたため、自分の環境で成功した流れとなります。
(補足)Docker Engineのインストール
$ sudo yum update
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin
$ sudo systemctl start docker
$ sudo systemctl enable docker
$ sudo docker --version
Docker version 23.0.1, build a5ee5b1
(補足)Docker Composeのインストール
$ sudo curl -SL https://github.com/docker/compose/releases/download/v2.4.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
Docker Compose version v2.4.1
(補足)dockerグループに一般ユーザー追加
$ sudo usermod -aG docker [一般ユーザー名]
Dockerの現状確認
構築に入る前にDockerインストール直後のDockerの状態を確認しておきます。
$ docker image ls # Dockerイメージはありません。
REPOSITORY TAG IMAGE ID CREATED SIZE
$ docker container ls -a # Dockerコンテナももちろんありません。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ docker volume ls # Dockerのボリュームもありません。
DRIVER VOLUME NAME
$ docker network ls # Dockerのネットワークはデフォルトで3つ作られています。
NETWORK ID NAME DRIVER SCOPE
704184225f25 bridge bridge local
0ab7ffc72fa6 host host local
2eee63585150 none null local
Docker Composeでの構築の場合
それではまずDocker Composeで超簡単にWordPressを作ってみたいと思います。
参考にしたドキュメントは以下になります。
クィックスタート: Compose と WordPress
手順
公式ドキュメントと同じですので、スキップしていただいて問題ありません。
プロジェクトディレクトリはproject_wordpress
にしました。
$ mkdir project_wordpress && cd project_wordpress
[project_wordpress]$ touch docker-compose.yml
[project_wordpress]$ vi docker-compose.yml # docker-compose.yml編集
[project_wordpress]$ cat docker-compose.yml
version: '3'
services:
db:
image: mysql:5.7
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:
[project_wordpress]$ docker-compose up -d
[+] Running 34/34
⠿ db Pulled
(省略)
⠿ wordpress Pulled
(省略)
[+] Running 4/4
⠿ Network project_wordpress_default Created
⠿ Volume "project_wordpress_db_data" Created
⠿ Container project_wordpress-db-1 Started
⠿ Container project_wordpress-wordpress-1 Started
これだけで構築完了です。
http://[ホスト名]:8000
にアクセスすると、WordPressの初期画面が出てきます。
でもこれじゃなにが起きているのかわからない。
確認していきます。
行われていること
ログの確認
まずコンソールに表示されたログをちゃんと確認します。
⠿ Network project_wordpress_default Created
⠿ Volume "project_wordpress_db_data" Created
⠿ Container project_wordpress-db-1 Started
⠿ Container project_wordpress-wordpress-1 Started
project_wordpress_default
というDockerネットワークが作られています。
project_wordpress_db_data
というDockerボリュームが作られています。
project_wordpress-db-1
というDBのコンテナがスタートしています。
project_wordpress-wordpress-1
というWordPressのコンテナがスタートしています。
コマンドでも確認してみます。
コマンド確認
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress latest 29cf1d10dc09 8 days ago 615MB
mysql 5.7 be16cf2d832a 3 weeks ago 455MB
$ docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8cb7f5a09961 wordpress:latest "docker-entrypoint.s…" 24 minutes ago Up 24 minutes 0.0.0.0:8000->80/tcp, :::8000->80/tcp project_wordpress-wordpress-1
bdd18a13020e mysql:5.7 "docker-entrypoint.s…" 24 minutes ago Up 24 minutes 3306/tcp, 33060/tcp project_wordpress-db-1
$ docker volume ls
DRIVER VOLUME NAME
local dc40f4bf1849138c97116b462ea5247b754baaea54960161b678307ff8de9e59
local project_wordpress_db_data
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
704184225f25 bridge bridge local
0ab7ffc72fa6 host host local
2eee63585150 none null local
d328d2b4d339 project_wordpress_default bridge local
docker image ls
からDBとWordPressのコンテナイメージがダウンロードされていることがわかります。
docker container ls -a
からDBとWordPressのコンテナが実行されていることがわかります。これはコンソールログからもわかりました。
dc40f4bf1849138c97116b462ea5247b754baaea54960161b678307ff8de9e59
とproject_wordpress_db_data
というDockerボリュームが作成されていることがわかります。
project_wordpress_default
というDockerネットワークが作られていることがわかります。
Dockerネットワークについて
これが一番わかりにくかったです。なぜなら、docker-compose.yml
にネットワークの作成の定義が書かれていないからです。
結論から言うと、Docker Composeをすると、プロジェクトに対してひとつのネットワークが作成されます。
ドキュメント(Compose の ネットワーク機能networking)に書かれていました。
引用します。
デフォルトで Compose はアプリに対して1つの ネットワーク を作成します。サービス用の各コンテナはデフォルトのネットワークに接続し、そのネットワーク上で他のコンテナと相互に「 接続可能reachable 」になります。そして、コンテナ名と同じホスト名として、お互いが「 発見可能discoverable 」になります。
よって、project_wordpress_default
というDockerネットワークはproject_wordpress
(作成したディレクトリ名)に基づいて作成され、DBコンテナとWordPressコンテナの両方から「接続可能」なネットワークとして作成されたことがわかります。
また以下のコマンドで、WordPressコンテナとDBコンテナに同じDockerネットワークが使用されていることがわかります。
DockerネットワークのIDを確認して、それがそれぞれのコンテナにアタッチされていました。
$ docker network inspect project_wordpress_default
[
{
"Name": "project_wordpress_default",
"Id": "d328d2b4d339140f90dda37da75c171c83ca8fc13981b7c050bb120776ffde19",
(省略)
$ docker container inspect bdd18a13020e | grep Network
"NetworkMode": "project_wordpress_default",
"NetworkSettings": {
"Networks": {
"NetworkID": "d328d2b4d339140f90dda37da75c171c83ca8fc13981b7c050bb120776ffde19",
$ docker container inspect 8cb7f5a09961 | grep Network
"NetworkMode": "project_wordpress_default",
"NetworkSettings": {
"Networks": {
"NetworkID": "d328d2b4d339140f90dda37da75c171c83ca8fc13981b7c050bb120776ffde19",
Dockerボリュームについて
2つのボリュームが作成されていました。
docker-compose.yml
に記載されている以下の部分があります。
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
volumes:
db_data:
これはdb_data
というボリュームを作って、mysql:5.7
イメージで作られるDBコンテナにアタッチする(マウントポイントは/var/lib/mysql
)という記述ですね。
dc40f4bf1849138c97116b462ea5247b754baaea54960161b678307ff8de9e59
というボリュームは、WordPressコンテナに接続されたボリュームとなります。
以下のコマンドで確認できました。
$ docker container inspect 8cb7f5a09961 | grep volume
"Type": "volume",
"Source": "/var/lib/docker/volumes/dc40f4bf1849138c97116b462ea5247b754baaea54960161b678307ff8de9e59/_data",
docker container inspect
コマンドでWordPressコンテナの詳細を表示し、その中でvolumeに関するところをgrep
で抜き出しました。
確かにWordPressコンテナに接続されていました。
ちなみに、docker container inspect
コマンドでDBコンテナの詳細を表示すると、db_data
がDBコンテナに接続されていることがわかります。
$ docker container inspect bdd18a13020e | grep volume
"Type": "volume",
"Type": "volume",
"Source": "/var/lib/docker/volumes/project_wordpress_db_data/_data",
Dockerイメージのダウンロードとコンテナの実行
docker container run
コマンドでコンテナを実行しようとすると、もし土台となるイメージが無かった場合はダウンロードされます。
今回のDocker Composeでも同じことが行われています。
MySQLとWordPressのイメージは無かったためダウンロードが行われ、そこからDBコンテナとWordPressコンテナが実行されました。
また、depends_on
句によって、docker-compose up
した場合、DBコンテナが起動してからWordPressコンテナが起動するようになっています。
もし、docker-compose stop
をした場合、WordPressコンテナが停止してからDBコンテナが停止します。
あと、それぞれのコンテナにrestart: always
が指定されていますが、こちらはホストOSが起動したときに常に再起動するというオプションです。
最後に、environment:
句でコンテナに環境変数を渡しています。
削除
先ほど作ったものをすべて削除します。
$ docker-compose down --volumes
[+] Running 4/4
⠿ Container project_wordpress-wordpress-1 Removed
⠿ Container project_wordpress-db-1 Removed
⠿ Volume project_wordpress_db_data Removed
⠿ Network project_wordpress_default Removed
Dockerイメージは残るので、下記コマンドで削除しました。
タグありのDockerイメージの一括削除です。
$ docker rmi `docker images -f "dangling=false" -q`
ひとつひとつ手作業でやった場合
では、Docker Composeを使用せずにWordPressをコンテナで構築してみます。
ひとつひとつ手作業で行ってみたいと思います。
手順
Dockerネットワークの作成
DBコンテナとWordPressコンテナをつなぐDockerネットワークを作成します。
project2_wordpress_default
という名前にしました。
$ docker network create --driver bridge project2_wordpress_default
0626487a5a9dcc78ff5f34e64a97f2969e799f5c56bd00c89f027936031e95b9
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
ef0af5aae626 bridge bridge local
0ab7ffc72fa6 host host local
2eee63585150 none null local
0626487a5a9d project2_wordpress_default bridge local
ボリュームの作成
Dockerのボリュームを作成します。
ここではDBコンテナにアタッチするボリュームのみ作成します。(名前はproject2_wordpress_db_data
です)
WordPressコンテナのボリュームはWordPressコンテナを作成すれば自動的に作成されます。
$ docker volume create --driver local --name project2_wordpress_db_data
project2_wordpress_db_data
$ docker volume ls
DRIVER VOLUME NAME
local project2_wordpress_db_data
Dockerイメージのダウンロード
Dockerコンテナを走らせようとすれば、無いイメージはダウンロードされますが、ここではDockerイメージのダウンロードを個別に行ってみます。
$ docker image pull wordpress
Using default tag: latest
latest: Pulling from library/wordpress
(省略)
Status: Downloaded newer image for wordpress:latest
docker.io/library/wordpress:latest
$ docker image pull mysql:5.7
5.7: Pulling from library/mysql
(省略)
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
wordpress latest 29cf1d10dc09 9 days ago 615MB
mysql 5.7 be16cf2d832a 3 weeks ago 455MB
IMAGE ID
を見てみると、Docker Composeのときにダウンロードしたイメージと同一であることがわかります。
DBコンテナの作成と実行
DBコンテナをスタートさせます。
docker container run \
--restart=always \
--network=project2_wordpress_default \
--volume=project2_wordpress_db_data \
--name=project2_wordpress-db-1 \
-e MYSQL_ROOT_PASSWORD=somewordpress \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wordpress \
-e MYSQL_PASSWORD=wordpress \
-d mysql:5.7
-
--restart=always
はdocker-compose.yml
の中でも指定されていたオプションです。 -
--network=project2_wordpress_default
で作成したDockerネットワークをアタッチしています。 -
--volume=project2_wordpress_db_data
で作成したDockerボリュームをバインドマウントしています。 -
--name=project2_wordpress-db-1
でDBコンテナの名前を指定しています。これはWordPressコンテナから参照されます。 -
-e
オプションで環境変数を指定しています。これはdocker-compose.yml
でも指定されていたものです。 -
-d
でデタッチモードでスタートします。これがないとプロンプトが返ってきません。
WordPressコンテナをスタートさせます。
$ docker container run \
--restart=always \
--network=project2_wordpress_default \
--name=project2_wordpress-wordpress-1 \
-e WORDPRESS_DB_HOST="project2_wordpress-db-1:3306" \
-e WORDPRESS_DB_USER=wordpress \
-e WORDPRESS_DB_PASSWORD=wordpress \
-p 8000:80 \
-d wordpress:latest
-
--restart=always
はdocker-compose.yml
の中でも指定されていたオプションです。 -
--network=project2_wordpress_default
で作成したDockerネットワークをアタッチしています。 -
--name=project2_wordpress-wordpress-1
でWordPressコンテナの名前を指定しています。 -
-e
オプションで環境変数を指定しています。docker-compose.yml
で指定していたものと同じですが、WORDPRESS_DB_HOST="project2_wordpress-db-1:3306"
だけはDBコンテナの名前(ホスト名)を直で指定しています。 -
-p 8000:80
でポートのマッピングをしています。docker-compose.yml
にも書かれていました。
http://[ホスト名]:8000
にアクセスすれば、WordPressの初期画面が表示されます。
所感
Docker Composeの仕組みがようやく少しわかった!
Dockerが学習コストが高いと言われる理由が少しわかった!
動きと中身が理解できてよかった!
Docker Composeは便利ですが、内容を理解して使わないとモヤモヤしてしまいますね。
ドキュメントをしっかりと読みながら使っていこうと思いました。
参考サイト