この記事
先日Docker及びCloud Runについての勉強会を開催しました。
本記事は、その時用意した資料となります。
目的
改めて、コンテナとは?というところから説明しつつ
- 代表的なコンテナエンジンであるDocker
- Google CloudのコンテナデプロイサービスであるCloud Run
について学んでもらえたらと考えています
コンテナでWordPressをデプロイしてみよう
ここからは教材として、有名なコンテンツマネージメントシステム(CMS)であるWordPressを使っていきたいと思います
WordPressはコンテンツの管理にデータベースを利用します
コンテナは基本的に「1コンテナ1サービス」とするのがベストプラクティスです
1 つのコンテナーには 1 つのサービスを割り当てるということにすれば、気にかける箇所が絞られるので、一般的にはこれが推奨されます。
(ドキュメント)
ですので今回は、WordPressとデータベースは別々に稼働させます
流れとしては以下の通りとなります
- ローカルに、WordPress用とデータベース用のコンテナをデプロイする
- Cloud RunでWordPressを構築する
※ 注意点
1, 2を通してDockerが、更に2ではgcloudが必要となります
ローカルに準備するのが難しい場合は、GCのコンソールからCloud Shellを起動することで実施することも可能です
ローカルに、WordPress用とデータベース用のコンテナをデプロイする
まずはローカルでWordPress、データベースの両方をデプロイし、コンテナ間通信について確認してみましょう
構成としては以下のようになります
- コンテナ
- wp : WordPressが稼働
- db : MySQLが稼働
- db_data (ボリューム) : データベースのデータを保存する領域
- my_net (Dockerネットワーク) : Docker内のネットワーク
- コンテナ間通信、コンテナ-ホスト間通信を実現
では上記の構成に基づいて、順に構築をしていきましょう
早速コンテナを、と行きたいのですが、まずはコンテナ起動時に必要となる「ボリューム」と「Dockerネットワーク」を作成します
ボリュームの作成
「コンテナの特徴 : 揮発性」で話しましたが、コンテナは破棄される時に中身をすべて失います
しかしそれではデータベースとして機能しません
そのような場合、「コンテナから参照できる、データを永続的に保存する場所」をホストに作成することで対処します
これをボリュームといいます
ボリュームはdocker volume create ${ボリューム名}
で作成可能です
Dockerネットワークの作成
次にDockerネットワークを作成します
コマンドはdocker network create ${ネットワーク名}
となります
※ 細かい話
Dockerネットワークにはいくつか種類がありますが、指定しなければブリッジ・ネットワークが作成されます
ブリッジ・ネットワークの特徴は
- 同じネットワークに所属しているコンテナ同士は通信が可能
- 仮想ブリッジを通して、ホストと通信が可能
- コンテナ名で名前解決が可能
- ただし、初期から存在するブリッジ・ネットワーク「bridge」では名前解決不可能(ドキュメント)
データベース用のコンテナデプロイ
今回使用するMySQLコンテナは、「hello-world」同様既に存在するDockerイメージをそのままデプロイします
コマンドは以下のとおりです
docker run -d --name db --net my_net -v db_data:/var/lib/mysql --env-file .env mysql:5.7
-
-d
: コンテナをバックグラウンドで実行 -
--name db
: コンテナに名前を付与 -
--net my_net
: コンテナが所属するネットワークを指定 -
-v db_data:/var/lib/mysql
: ボリュームの割り当て- ${ボリューム名}:${コンテナ側のパス}
- ちなみにホスト側のディレクトリをバインドさせることも可能
-
--env-file .env
: 環境変数をファイルで指定- .envファイルについては後述してます
-
mysql:5.7
: Dockerイメージを指定
WordPress用のコンテナデプロイ
WordPressに関してもDockerイメージが公開されており、それをそのままデプロイしても十分起動します
が、今回はあえて一手間加えて、WordPressのプラグインを1つ事前にダウンロードしておきます
その場合、まずはオリジナルのDockerイメージを作成しておく必要があります
Dockerイメージの作成に用いるDockerfileは後述しています(既に説明したRUN
命令を使ってます)
このDockerfileからDockerイメージを作成するコマンドは以下のとおりです
docker build -t my_db:test .
-
-t my_db:test
: Dockerイメージのリポジトリとタグを指定する(ドキュメント) -
.
: Dockerfileが存在するディレクトリを指定
※ 細かい話
- Dockerfileのファイル名が「Dockerfile」以外の場合は、
-f
でファイル名を指定する必要があります -
-t
が無いとリポジトリ、タグ共にとなります- 一応イメージIDを指定することでコンテナの起動は可能です
Dockerイメージ「my_db:test」がこれで作成されたので、あとはコンテナをデプロイしましょう
docker run -d --name wp --net my_net -e WORDPRESS_DB_HOST=db:3306 --env-file .env -p 8000:80 my_wp:test
-
-e WORDPRESS_DB_HOST=db:3306
: このようにして環境変数を指定することも可能です -
-p 8000:80
: ホストにおいて、localhostの8000番ポートにアクセスすると、コンテナの80番ポートに繋がります- 厳密には
${IPアドレス}:${ホスト側のポート}:${コンテナ側のポート}
という指定になります
- 厳密には
コマンド&各種ファイル
コマンド
# ボリューム及びネットワークの作成
~/wordpress$ docker volume create db_data
~/wordpress$ docker network create my_net
# データベース用コンテナのデプロイ
~/wordpress$ cd db
~/wordpress/db$ ls -a
. .. .env
~/wordpress/db$ docker run -d --name db --net my_net -v db_data:/var/lib/mysql --env-file .env mysql:5.7
# WordPress用コンテナのデプロイ
~/wordpress/db$ cd ../wp/
~/wordpress/wp$ ls -a
. .. .dockerignore .env Dockerfile
~/wordpress/wp$ docker build -t my_wp:test .
~/wordpress/wp$ docker run -d --name wp --net my_net -e WORDPRESS_DB_HOST=db:3306 --env-file .env -p 8000:80 my_wp:test
Dockerfile
FROM wordpress:latest
RUN apt-get update -y && apt-get install -y unzip
RUN curl -o /tmp/custom-post-type-ui.1.12.1.zip -L https://downloads.wordpress.org/plugin/custom-post-type-ui.1.12.1.zip \
&& unzip /tmp/custom-post-type-ui.1.12.1.zip -d /tmp/ \
&& mv /tmp/custom-post-type-ui /usr/src/wordpress/wp-content/plugins/
.env
データベース用
MYSQL_ROOT_PASSWORD=${MySQL管理者ユーザ「root」用パスワード}
MYSQL_DATABASE=wordpress
MYSQL_USER=wordpress
MYSQL_PASSWORD=${MySQLユーザ「wordpress」用パスワード}
WordPress用
WORDPRESS_DB_USER=wordpress
WORDPRESS_DB_PASSWORD=${MySQLユーザ「wordpress」用パスワード}
各環境変数
-
wordpress
- WORDPRESS_DB_HOST : データベースのホスト名
- WORDPRESS_DB_USER : データベースのユーザ名
- WORDPRESS_DB_PASSWORD : 「WORDPRESS_DB_USER」で指定したユーザのパスワード
- WORDPRESS_DB_NAME : 使用するデータベース
-
mysql
- MYSQL_ROOT_PASSWORD : MySQL管理者ユーザ「root」用パスワード
- MYSQL_DATABASE : 起動時点で作成するデータベース
- MYSQL_USER : 起動時点で作成するユーザ
- MYSQL_PASSWORD : 「MYSQL_USER」で指定したユーザのパスワード
docker execコマンド
Dockerfileの一例を紹介しましたが、いざ自分で作成しようとすると
- ベースイメージにはどんなパッケージが入っているのか確かめたい
- 思ったように動作せず、トラブルシューティングがしたい
などといった考えが出てくると思います
そんな時はdocker exec
コマンドが便利です
こちらを使うと、実行中のコンテナ内でコマンドを実行することができます
基本的には以下のように入力します
docker exec -it ${コンテナ名} ${コンテナで実行したいコマンド}
-it
についてはちょっとややこしいのですが、このオプションが無いと正しく標準入力、標準出力がおこなわれなくなります
初めのうちは一旦つけるようにし、ある程度Dockerの理解が進んできたら詳しく勉強すればいいと思います
このコマンドを使うと、コンテナのシェルで作業することも可能になります
$ docker exec -it wp bash
root@7b979b065660:/var/www/html# ps x
PID TTY STAT TIME COMMAND
1 ? Ss 0:00 apache2 -DFOREGROUND
28 pts/0 Ss 0:00 bash
38 pts/0 R+ 0:00 ps x
root@7b979b065660:/var/www/html#
Docker Compose
先程までは都度コマンドを叩き、ボリューム、ネットワーク及びコンテナの作成を行っていました
ただ、docker run
などは必要なオプションも多く、毎回記載するのは大変です
更に作成順なども考慮しないといけません(WordPressはデータベースのあとに作成したいなど)
Docker ComposeはそのようなDocker管理を楽にしてくれるツールです
Docker Composeでは、「docker-compose.yml」ファイルを用いて構成を定義します
今回の場合は以下のようになります
version: '3'
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
networks:
- my_net
env_file: ./db/.env
restart: always
wordpress:
depends_on:
- db
build: ./wp/
networks:
- my_net
ports:
- "8000:80"
environment:
WORDPRESS_DB_HOST: db:3306
env_file: ./wp/.env
restart: always
volumes:
db_data:
networks:
my_net:
-
restart: always
: コンテナ終了時、常に再起動を行う(明示的な停止は例外)
ディレクトリ構成
wordpress/
├── db
│ └── .env
├── docker-compose.yml
└── wp
├── .dockerignore
├── .env
└── Dockerfile
上記のようなファイルを用意した上で
docker-compose up -d --build
を実行すると、先程作成したのと同じ環境が作成できます