2re funの各プロジェクトでは、インフラ構築に一貫してDockerを使っています。この2re blog自体もWordPress+MySQLをDocker Composeで構築しており、「2re blogの技術構成|WordPress・Docker・MySQLで作る個人ブログ基盤」で紹介した通りです。今回は一歩戻って、Dockerの基本的な使い方を、実際にこのブログで使っているdocker-compose.ymlを例にしながら整理しておきます。
Dockerとは
Dockerは、アプリケーションとその実行環境をまとめて「コンテナ」という単位でパッケージ化し、どのマシンでも同じように動かせるようにするツールです。「自分のPCでは動くのに本番サーバーでは動かない」といった環境差異の問題を防げるのが最大のメリットで、個人開発でもチーム開発でも広く使われています。
基本概念:イメージ・コンテナ・Dockerfile
Dockerを理解する上でまず押さえておきたいのが、次の3つの用語です。
- イメージ(Image):アプリケーションの実行に必要なファイルや設定をまとめた、いわば「設計図」。読み取り専用のテンプレート。
- コンテナ(Container):イメージを元に実際に起動した、動いているプロセスの実体。同じイメージから複数のコンテナを起動できる。
- Dockerfile:イメージをどう作るかを記述した設計書。ベースイメージの指定やコマンドの実行手順をテキストで書く。
「Dockerfileからイメージをビルドし、イメージからコンテナを起動する」という流れがDockerの基本サイクルです。
よく使う基本コマンド
単体のDockerコマンドとしては、まず次のあたりを覚えておくと一通りの操作ができます。
docker build -t 任意の名前 .:カレントディレクトリのDockerfileからイメージをビルドdocker run -d -p 8080:80 イメージ名:イメージからコンテナをバックグラウンド起動し、ポートを公開docker ps/docker ps -a:起動中/すべてのコンテナ一覧を確認docker logs -f コンテナ名:コンテナのログをリアルタイムで確認docker exec -it コンテナ名 bash:起動中のコンテナ内でシェルを実行docker stop コンテナ名/docker rm コンテナ名:コンテナの停止・削除docker images/docker rmi イメージ名:イメージの一覧・削除
複数コンテナはDocker Composeでまとめて管理する
WordPress+MySQLのように複数のコンテナを組み合わせて使う場合、docker runをコンテナごとに実行するのは手間がかかります。そこで使うのがDocker Composeです。docker-compose.ymlというファイルに必要なコンテナ(サービス)をまとめて定義しておけば、コマンド1つでまとめて起動・停止できます。
docker compose up -d:定義したサービスをまとめてバックグラウンド起動docker compose ps:サービスの起動状況を確認docker compose logs -f サービス名:特定サービスのログを確認docker compose exec サービス名 bash:サービスのコンテナ内に入るdocker compose down:サービスをまとめて停止・削除(ボリュームは残る)
実例:2re blogのdocker-compose.ymlを読み解く
実際にこの2re blogで使っているdocker-compose.ymlを例に、書き方のポイントを見てみます。
services:
mysql:
image: mysql:8.4
container_name: blo-2refun-db
restart: unless-stopped
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE:-wordpress}
MYSQL_USER: ${MYSQL_USER:-wordpress}
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-wordpress}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root}
volumes:
- blo-db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-root}"]
interval: 5s
timeout: 5s
retries: 20
wordpress:
image: wordpress:php8.3-apache
container_name: blo-2refun-wordpress
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_NAME: ${MYSQL_DATABASE:-wordpress}
WORDPRESS_DB_USER: ${MYSQL_USER:-wordpress}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD:-wordpress}
volumes:
- blo-wp-data:/var/www/html
ports:
- "127.0.0.1:8081:80"
depends_on:
mysql:
condition: service_healthy
volumes:
blo-db-data:
blo-wp-data:
ポイントは次の4つです。
- 環境変数は.envファイルに切り出す:
${MYSQL_PASSWORD:-wordpress}のように書くと、.envで値を上書きしつつ、未設定でも動くデフォルト値を持たせられます。パスワードなどの秘匿情報をコードに直書きせずに済みます。 - データは名前付きボリュームに永続化する:
blo-db-dataやblo-wp-dataのような名前付きボリュームにデータを保存しておけば、コンテナを削除して作り直してもデータは消えません。 - healthcheckとdepends_onで起動順序を制御する:MySQLコンテナに
healthcheckを設定し、WordPress側のdepends_onでcondition: service_healthyを指定することで、DBが実際に接続可能になってからWordPressを起動できます。単なるdepends_onだけだと、コンテナは起動していてもDBの準備が間に合わずエラーになることがあります。 - ポートは必要な範囲だけ公開する:
127.0.0.1:8081:80のようにホスト側のバインド先をローカルホストに絞ることで、外部から直接コンテナのポートへアクセスされるのを防いでいます。本番公開はCaddyなどのリバースプロキシ経由にしています。
Dockerを使うときに気をつけていること
2re funの各プロジェクトでDockerを使う際、次の点を意識しています。
- 本番運用するコンテナには
restart: unless-stoppedを設定し、サーバー再起動時に自動で立ち上がるようにする - 秘匿情報は
.envにまとめ、.gitignoreでリポジトリに含めない - コンテナ名やボリューム名にプロジェクト名のプレフィックスを付け、複数プロジェクトを1台のVPS上で動かしても衝突しないようにする
- まず
docker compose logsでログを確認してから、必要に応じてdocker compose execでコンテナに入って調査する
まとめ
Dockerは「イメージからコンテナを起動する」というシンプルな仕組みですが、Docker Composeを使うことで複数コンテナの構成もコード化でき、環境の再現性が大きく上がります。2re funでは、この2re blogに限らず各プロジェクトのインフラをDocker Composeでコード化しており、それぞれの技術構成はこのブログで随時紹介していく予定です。あわせて「2re blogの技術構成」もご覧ください。
コメントを残す