【3-5】Docker Compose実践編!WordPressとNode.js環境をコードで構築
Docker Compose実践編!WordPressとNode.js環境をコードで構築
はじめに
前回の記事では、docker-compose.ymlの基本を学び、コマンド一発で複数のコンテナを起動・停止する強力さを体験しました。 今回はその知識をさらに発展させ、より実践的なマルチコンテナアプリケーションを2種類構築していきます。一つは世界中で愛用されているCMS 「WordPress」の本格的な実行環境。もう一つは、モダンな開発で人気の 「Node.js + MongoDB + Redis」 という開発スタックです。
この記事では、Dockerfileとの連携や、コンテナ間の接続設定など、実務で必須となるDocker Composeの応用テクニックを、具体的なアプリケーションの構築を通じて習得します。
実践①: WordPress + MySQL + phpMyAdmin構成
ブログやWebサイトを構築するための本格的な環境を、Docker Composeで一気に立ち上げます。
Step 1: docker-compose.ymlの設計と作成
WordPress本体、データベース(MySQL)、データベース管理ツール(phpMyAdmin)の3つのサービスを連携させるための設計図を作成します。
# 作業ディレクトリを作成して移動
cd ~
mkdir ~/wordpress-compose
cd ~/wordpress-compose
# docker-compose.ymlを作成
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
# --- WordPress本体のサービス ---
wordpress:
image: wordpress:latest
container_name: my-wordpress
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_pass
WORDPRESS_DB_NAME: wordpress_db
volumes:
- wordpress-data:/var/www/html
depends_on:
- db
networks:
- wp-network
# --- データベース(MySQL)のサービス ---
db:
image: mysql:8.0
container_name: wp-mysql
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: wordpress_db
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_pass
volumes:
- mysql-data:/var/lib/mysql
networks:
- wp-network
# --- DB管理ツール(phpMyAdmin)のサービス ---
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: wp-phpmyadmin
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_USER: root
PMA_PASSWORD: root_password
depends_on:
- db
networks:
- wp-network
volumes:
wordpress-data:
mysql-data:
networks:
wp-network:
driver: bridge
EOF
環境変数はどのように連携しているのか?
この設定の核心はwordpressサービスとdbサービスのenvironmentセクションにあります。なぜこれらの値は対応している必要があるのでしょうか?
答えは、「wordpressコンテナがdbコンテナの『クライアント』だから」です。
wordpressイメージは、「起動時にこれらの環境変数があったら、その情報を使ってデータベースに接続しに行く」ようにプログラムされています。一方、mysqlイメージは「起動時にこれらの環境変数があったら、その情報でデータベースとユーザーを初期作成する」ように作られています。
つまり、私たちは2つの異なるコンテナ(プログラム)に、それぞれが必要とする形式で、同じ接続情報を教えてあげているのです。
| wordpressサービス(接続する側)の質問 | dbサービス(接続される側)の回答 |
|---|---|
WORDPRESS_DB_HOST: DBサーバーはどこ? |
services:で定義したdbというサービス名 |
WORDPRESS_DB_USER: ユーザー名は? |
MYSQL_USER: wordpressというユーザーを作っておく |
WORDPRESS_DB_PASSWORD: パスワードは? |
MYSQL_PASSWORD: パスワードはwordpress_passだよ |
WORDPRESS_DB_NAME: データベース名は? |
MYSQL_DATABASE: wordpress_dbというDBを作っておく |
このように、片方で「作成するユーザー情報」、もう片方で「接続しにいくユーザー情報」を正確に一致させることで、2つのコンテナは初めて正しく連携できるのです。
Step 2: 環境の起動とデータ永続化の確認
# WordPress環境を起動
docker compose up -d
ブラウザでhttp://192.168.3.101:8080にアクセスし、WordPressの初期設定を完了させます。簡単なテスト投稿を一つ作成した後、docker compose downで一度環境を破棄し、再度docker compose up -dで立ち上げてみましょう。
以前作成した投稿がそのまま表示されれば、volumesによってデータが正しく永続化されている証拠です。
実践②: Node.js + MongoDB + Redis 開発環境
次に、Dockerfileと連携させ、よりモダンなWebアプリケーション開発で使われる技術スタックを構築します。
Step 1: Node.js APIの準備
catコマンドで、APIサーバーのソースコード(package.json、server.js)、そしてビルドするためのDockerfileを一気に作成します。
# 作業ディレクトリとソースコード一式を作成
cd ~
mkdir -p ~/node-mongo-redis/app
cd ~/node-mongo-redis
# package.json の作成
cat > app/package.json << 'EOF'
{
"name": "node-api-app",
"version": "1.0.0",
"main": "server.js",
"scripts": { "start": "node server.js" },
"dependencies": {
"express": "^4.18.0",
"mongoose": "^7.0.0",
"redis": "^4.6.0"
}
}
EOF
# server.js の作成
cat > app/server.js << 'EOF'
const express = require('express');
const mongoose = require('mongoose');
const redis = require('redis');
const app = express();
const port = 3000;
// MongoDB接続 (mongoはサービス名)
mongoose.connect('mongodb://mongo:27017/testdb');
// Redis接続 (redisはサービス名)
const client = redis.createClient({ url: 'redis://redis:6379' });
client.connect();
app.get('/', async (req, res) => {
res.json({ message: 'Node.js + MongoDB + Redis API', status: 'running' });
});
app.listen(port, () => {
console.log(`API server running at http://localhost:${port}`);
});
EOF
# Dockerfile の作成
cat > app/Dockerfile << 'EOF'
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
EOF
Step 2: フルスタック環境のdocker-compose.yml作成
Node.js API、MongoDB、Redis、そしてDB管理ツールの4つのサービスを連携させるdocker-compose.ymlを作成します。
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
# --- 自作のNode.js APIサービス ---
api:
build: ./app
container_name: node-api
ports:
- "3000:3000"
volumes:
- ./app:/app
- /app/node_modules
depends_on:
- mongo
- redis
networks:
- dev-network
# --- MongoDBサービス ---
mongo:
image: mongo:latest
container_name: dev-mongo
volumes:
- mongo-data:/data/db
networks:
- dev-network
# --- Redisサービス ---
redis:
image: redis:alpine
container_name: dev-redis
volumes:
- redis-data:/data
networks:
- dev-network
# --- MongoDB管理ツール ---
mongo-express:
image: mongo-express
container_name: mongo-admin
ports:
- "8082:8081"
environment:
ME_CONFIG_MONGODB_SERVER: mongo
depends_on:
- mongo
networks:
- dev-network
volumes:
mongo-data:
redis-data:
networks:
dev-network:
driver: bridge
EOF
開発効率を上げる高度なvolumes設定
このapiサービスのvolumes設定は、開発効率を劇的に向上させるための重要なテクニックです。
volumes:
- ./app:/app
- /app/node_modules
./app:/app: ホストOSのappディレクトリをコンテナの/appにマウントします。これにより、ホスト側でソースコード(例: server.js)を編集すると、コンテナを再起動することなく即座に変更が反映されます(ホットリロード)。
/app/node_modules: こちらは「名前なしボリューム」です。Dockerfile内のRUN npm installでインストールされたコンテナ内のnode_modulesを、ホスト側の空のnode_modulesで上書きしてしまうのを防ぎます。これにより、コンテナは自身のnode_modulesを使い続け、ホスト側は汚染されません。
Step 3: 開発環境の起動と動作確認
build:ディレクティブを使っているため、--buildオプション付きで起動します。
docker compose up -d --build
ターミナルからcurl http://localhost:3000を実行してAPIからの応答を確認し、ブラウザでhttp://192.168.3.101:8082にアクセスしてMongo Expressの管理画面が表示されることを確認しましょう。
まとめ
Docker Composeを使いこなすことで、複雑なアプリケーション環境でも、誰でも、どこでも、コマンド一発で再現できるようになりました。これは、現代の開発・運用において非常に強力な武器となります。
Discussion