WordPress を Docker で最速構築:開発/本番の環境差分をなくす手順

WordPress のローカル開発環境を本格的に構築しようとした際、「開発環境では動くのに本番環境で動かない」という経験はありませんか。この問題の根本的な解決策が Docker による環境統一です。
Docker を活用することで、開発から本番まで完全に同一の環境で WordPress を動かすことができます。今回は、実際のコードとともに、最短ルートで WordPress 環境を Docker 化する手順をご紹介します。環境差分によるトラブルを根絶し、効率的な開発ワークフローを手に入れましょう。
背景
従来の WordPress 環境構築の課題
従来の WordPress 環境構築では、多くの開発者が同じような課題に直面してきました。
まず、開発者それぞれのローカル環境が異なることが大きな問題となります。PHP のバージョン、Apache/Nginx の設定、MySQL のバージョンなど、微細な違いが予期しないエラーを引き起こします。
javascript// 開発環境: PHP 8.1
if (version_compare(PHP_VERSION, '8.1.0', '>=')) {
// 新しい構文が使える
$result = match($status) {
'active' => 'アクティブ',
'inactive' => '非アクティブ',
default => '不明'
};
}
上記のようなコードが開発環境では正常に動作しても、本番環境が PHP 7.4 だった場合、構文エラーが発生してしまいます。
さらに、チーム開発においては「私の環境では動く」問題が頻発します。新しいメンバーが参加するたびに、環境構築に時間を取られ、プロジェクトの進行に影響を与えてしまいます。
WordPress 特有の課題として、プラグインやテーマの依存関係も複雑になりがちです。開発環境と本番環境でプラグインのバージョンが異なると、予期しない動作が発生する可能性があります。
yaml# 従来の課題例
開発環境:
- PHP: 8.1
- MySQL: 8.0
- WordPress: 6.3
- プラグインA: 2.1.0
本番環境:
- PHP: 7.4 ← バージョン違い
- MySQL: 5.7 ← バージョン違い
- WordPress: 6.2 ← バージョン違い
- プラグインA: 2.0.5 ← バージョン違い
Docker による解決アプローチ
Docker は、これらの課題を根本的に解決する強力なソリューションです。コンテナ技術により、アプリケーションとその実行環境を丸ごとパッケージ化できます。
Docker の最大の利点は「コンテナとして動作する環境の完全な再現性」です。開発者のローカル環境、ステージング環境、本番環境すべてで、全く同じコンテナイメージを使用できます。
mermaidflowchart LR
dev[開発環境] -->|同一イメージ| container[Docker コンテナ]
staging[ステージング環境] -->|同一イメージ| container
prod[本番環境] -->|同一イメージ| container
container --> wp[WordPress アプリ]
container --> php[PHP 8.1]
container --> apache[Apache 2.4]
上図のように、すべての環境で同一の Docker イメージを使用することで、環境差分を完全になくすことができます。
Docker Compose を使用することで、WordPress 本体だけでなく、MySQL、Redis、Nginx など複数のサービスを組み合わせた環境も簡単に管理できます。
yaml# Docker Compose による統一環境
services:
wordpress:
image: wordpress:6.3-php8.1-apache
mysql:
image: mysql:8.0
redis:
image: redis:7.0
さらに、バージョン管理システムとの連携により、環境設定もコードとして管理できるようになります。これにより、環境の変更履歴や、特定の時点での環境復元も可能となります。
課題
開発と本番の環境差分問題
開発と本番の環境差分は、WordPress 開発において最も深刻な問題の一つです。具体的にどのような問題が発生するのかを詳しく見てみましょう。
PHP バージョンの違いによる問題
開発環境で PHP 8.1 を使用していて、本番環境が PHP 7.4 の場合、以下のような問題が発生します。
php// PHP 8.1 で追加された Named Arguments
function create_post_meta($post_id, $meta_key, $meta_value, $unique = false) {
return add_post_meta(
post_id: $post_id,
meta_key: $meta_key,
meta_value: $meta_value,
unique: $unique
);
}
上記のコードは PHP 8.1 では正常に動作しますが、PHP 7.4 では構文エラーとなります。
データベースの違いによる問題
MySQL のバージョン違いにより、以下のような SQL の動作が変わることがあります。
sql-- MySQL 8.0 以降では動作するが、5.7 では異なる結果になる可能性
SELECT JSON_EXTRACT(meta_value, '$.price') as price
FROM wp_postmeta
WHERE meta_key = 'product_data'
ORDER BY price DESC;
WordPress 設定の差分
php// wp-config.php の設定が環境ごとに異なる例
define('WP_DEBUG', true); // 開発環境
define('WP_DEBUG', false); // 本番環境
define('WP_MEMORY_LIMIT', '256M'); // 開発環境
define('WP_MEMORY_LIMIT', '512M'); // 本番環境(より大きい)
これらの設定差分により、開発時には発見できなかった問題が本番環境で発生することがあります。
mermaidflowchart TD
dev_issue[開発環境での問題] --> hidden[見つからない問題]
hidden --> prod_deploy[本番デプロイ]
prod_deploy --> prod_error[本番エラー発生]
prod_error --> emergency[緊急対応]
emergency --> downtime[サービス停止]
style prod_error fill:#ff6b6b
style emergency fill:#ff6b6b
style downtime fill:#ff6b6b
上図が示すように、環境差分による問題は最終的にサービス停止という深刻な事態を招く可能性があります。
従来手法の限界
従来の環境構築手法には、根本的な限界があります。
手動セットアップの限界
各開発者が手動で環境をセットアップする場合、以下の問題が発生します。
bash# 開発者Aの環境構築手順
brew install php@8.1
brew install mysql@8.0
brew install composer
# 開発者Bの環境構築手順(微妙に異なる)
sudo apt-get install php8.1
sudo apt-get install mysql-server-8.0
curl -sS https://getcomposer.org/installer | php
同じ目的でも、OS やパッケージマネージャーの違いにより、微妙に異なる環境が構築されてしまいます。
XAMPP/MAMP の限界
XAMPP や MAMP といったパッケージソリューションも、以下の制約があります。
項目 | XAMPP/MAMP | 本番環境 | 問題 |
---|---|---|---|
OS | Windows/macOS | Linux | 異なる OS |
PHP 設定 | 開発用設定 | 本番用設定 | セキュリティ設定の差分 |
拡張モジュール | 標準セット | カスタム構成 | 必要な拡張が不足 |
データベース設定 | 緩い設定 | 厳格な設定 | 文字コードや照合順序の違い |
Vagrant の課題
Vagrant による仮想環境も一定の効果はありますが、以下の課題があります。
ruby# Vagrantfile の例
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y apache2 php mysql-server
# 長い初期化スクリプトが必要
SHELL
end
Vagrant は仮想マシン全体を起動するため、リソース消費が大きく、起動時間も長くなりがちです。また、仮想マシンの管理も複雑になります。
これらの従来手法の限界を克服するため、Docker による解決策が注目されています。
解決策
Docker Compose による環境統一
Docker Compose を使用することで、複数のサービスを組み合わせた WordPress 環境を簡単に管理できます。最も重要なのは、開発・本番すべての環境で同一の構成を使用することです。
まず、基本的なディレクトリ構造を確認しましょう。
textwordpress-docker/
├── docker-compose.yml
├── docker-compose.override.yml # 開発環境用オーバーライド
├── docker-compose.prod.yml # 本番環境用設定
├── Dockerfile
├── .env.example
├── .env
└── wordpress/
├── wp-content/
│ ├── themes/
│ └── plugins/
└── wp-config.php
基本となる docker-compose.yml
を作成します。この設定は開発・本番共通で使用する基盤となります。
yaml# docker-compose.yml - 基本設定
version: '3.8'
services:
wordpress:
build: .
restart: unless-stopped
environment:
WORDPRESS_DB_HOST: mysql
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: ${DB_NAME}
volumes:
- ./wordpress:/var/www/html
depends_on:
- mysql
mysql:
image: mysql:8.0
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
環境変数は .env
ファイルで管理し、機密情報をコードから分離します。
bash# .env ファイル
DB_NAME=wordpress
DB_USER=wp_user
DB_PASSWORD=secure_password_here
DB_ROOT_PASSWORD=root_password_here
WORDPRESS_TABLE_PREFIX=wp_
図で表すと、以下のような構成になります。
mermaidflowchart TB
compose[Docker Compose] --> wp_container[WordPress コンテナ]
compose --> mysql_container[MySQL コンテナ]
wp_container --> wp_volume[WordPress ボリューム]
mysql_container --> mysql_volume[MySQL データボリューム]
env_file[.env ファイル] --> compose
subgraph "共通基盤"
compose
env_file
end
subgraph "コンテナ群"
wp_container
mysql_container
end
この構成により、開発者全員が全く同じ WordPress 環境を瞬時に起動できるようになります。
マルチステージビルドの活用
Docker のマルチステージビルドを活用することで、効率的で軽量なイメージを作成できます。開発時には開発用のツールを含み、本番時には不要なファイルを除外した最適化されたイメージを作成します。
dockerfile# Dockerfile - マルチステージビルド
# ステージ1: 開発用ベース
FROM wordpress:6.3-php8.1-apache as development
# 開発用パッケージのインストール
RUN apt-get update && apt-get install -y \
git \
unzip \
vim \
wget \
&& rm -rf /var/lib/apt/lists/*
# Composer のインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# 開発用 PHP 設定
COPY php.ini-development /usr/local/etc/php/php.ini
# Xdebug のインストール(開発環境のみ)
RUN pecl install xdebug && docker-php-ext-enable xdebug
本番用のステージを定義します。
dockerfile# ステージ2: 本番用イメージ
FROM wordpress:6.3-php8.1-apache as production
# 必要最小限のパッケージのみインストール
RUN apt-get update && apt-get install -y \
&& rm -rf /var/lib/apt/lists/*
# 本番用 PHP 設定
COPY php.ini-production /usr/local/etc/php/php.ini
# セキュリティ強化
RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 755 /var/www/html
# ヘルスチェック用エンドポイント
COPY healthcheck.php /var/www/html/
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/healthcheck.php || exit 1
開発時と本番時でビルドターゲットを切り替えます。
yaml# docker-compose.override.yml - 開発環境用
version: '3.8'
services:
wordpress:
build:
context: .
target: development # 開発用ステージを使用
ports:
- '8080:80'
environment:
- XDEBUG_MODE=develop,debug
- XDEBUG_CONFIG=client_host=host.docker.internal
volumes:
- ./wordpress:/var/www/html
- ./logs:/var/log/apache2
yaml# docker-compose.prod.yml - 本番環境用
version: '3.8'
services:
wordpress:
build:
context: .
target: production # 本番用ステージを使用
environment:
- WORDPRESS_CONFIG_EXTRA=define('WP_DEBUG', false);
volumes:
- wordpress_data:/var/www/html
- ./uploads:/var/www/html/wp-content/uploads
マルチステージビルドの効果を図で表すと以下のようになります。
mermaidflowchart LR
dockerfile[Dockerfile] --> dev_stage[開発ステージ]
dockerfile --> prod_stage[本番ステージ]
dev_stage --> dev_image[開発用イメージ<br/>・Xdebug<br/>・Git<br/>・Composer<br/>・開発ツール]
prod_stage --> prod_image[本番用イメージ<br/>・最小構成<br/>・セキュリティ強化<br/>・パフォーマンス最適化]
dev_image --> dev_env[開発環境]
prod_image --> prod_env[本番環境]
style dev_image fill:#a8e6cf
style prod_image fill:#ffd93d
このアプローチにより、開発時の利便性と本番時の効率性を両立できます。
環境変数による設定管理
環境変数を活用した設定管理により、同一のコードで異なる環境設定を実現できます。これは WordPress の設定ファイルにも適用できます。
まず、環境別の設定ファイルを準備します。
bash# .env.development - 開発環境用
WORDPRESS_ENV=development
WORDPRESS_DEBUG=true
WORDPRESS_DEBUG_LOG=true
WORDPRESS_DEBUG_DISPLAY=true
WP_MEMORY_LIMIT=256M
DB_HOST=mysql
REDIS_HOST=redis
SITE_URL=http://localhost:8080
ADMIN_EMAIL=dev@example.com
bash# .env.production - 本番環境用
WORDPRESS_ENV=production
WORDPRESS_DEBUG=false
WORDPRESS_DEBUG_LOG=false
WORDPRESS_DEBUG_DISPLAY=false
WP_MEMORY_LIMIT=512M
DB_HOST=mysql
REDIS_HOST=redis
SITE_URL=https://example.com
ADMIN_EMAIL=admin@example.com
これらの環境変数を読み込む wp-config.php
を作成します。
php<?php
// wp-config.php - 環境変数を活用した設定
// 環境変数の読み込み
$wordpress_env = getenv('WORDPRESS_ENV') ?: 'development';
// データベース設定(環境変数から取得)
define('DB_NAME', getenv('DB_NAME'));
define('DB_USER', getenv('DB_USER'));
define('DB_PASSWORD', getenv('DB_PASSWORD'));
define('DB_HOST', getenv('DB_HOST'));
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
// デバッグ設定(環境に応じて切り替え)
define('WP_DEBUG', filter_var(getenv('WORDPRESS_DEBUG'), FILTER_VALIDATE_BOOLEAN));
define('WP_DEBUG_LOG', filter_var(getenv('WORDPRESS_DEBUG_LOG'), FILTER_VALIDATE_BOOLEAN));
define('WP_DEBUG_DISPLAY', filter_var(getenv('WORDPRESS_DEBUG_DISPLAY'), FILTER_VALIDATE_BOOLEAN));
Redis キャッシュの設定も環境変数で管理します。
php// Redis 設定
if (getenv('REDIS_HOST')) {
define('WP_REDIS_HOST', getenv('REDIS_HOST'));
define('WP_REDIS_PORT', getenv('REDIS_PORT') ?: 6379);
define('WP_REDIS_DATABASE', getenv('REDIS_DATABASE') ?: 0);
}
// メモリ制限の設定
define('WP_MEMORY_LIMIT', getenv('WP_MEMORY_LIMIT') ?: '256M');
// サイトURL の設定
define('WP_HOME', getenv('SITE_URL'));
define('WP_SITEURL', getenv('SITE_URL'));
セキュリティキーも環境変数で管理することで、より安全な運用が可能になります。
php// セキュリティキー(環境変数または自動生成)
$security_keys = [
'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY',
'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT'
];
foreach ($security_keys as $key) {
$value = getenv("WORDPRESS_{$key}");
if (!$value) {
// 環境変数が設定されていない場合は自動生成
$value = wp_generate_password(64, true, true);
}
define($key, $value);
}
具体例
基本的な Docker 構成
実際に動作する WordPress 環境を Docker で構築してみましょう。まず、プロジェクトディレクトリを作成し、必要なファイルを配置します。
bash# プロジェクトディレクトリの作成
mkdir wordpress-docker-project
cd wordpress-docker-project
# 必要なディレクトリ構造を作成
mkdir -p wordpress/wp-content/{themes,plugins,uploads}
mkdir -p mysql/data
mkdir -p logs
基本的な Dockerfile を作成します。この例では、公式 WordPress イメージをベースに、必要な拡張機能を追加しています。
dockerfile# Dockerfile
FROM wordpress:6.3-php8.1-apache
# 必要なPHP拡張機能をインストール
RUN docker-php-ext-install mysqli pdo pdo_mysql
# ImageMagick のインストール
RUN apt-get update && apt-get install -y \
libmagickwand-dev \
&& pecl install imagick \
&& docker-php-ext-enable imagick \
&& rm -rf /var/lib/apt/lists/*
# Redis 拡張機能のインストール
RUN pecl install redis && docker-php-ext-enable redis
# カスタム PHP 設定をコピー
COPY ./config/php.ini /usr/local/etc/php/conf.d/custom.ini
PHP の設定ファイルを作成します。
ini; config/php.ini
; メモリ制限
memory_limit = 256M
; ファイルアップロード設定
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
; エラー設定
log_errors = On
error_log = /var/log/php_errors.log
; セッション設定
session.cookie_secure = On
session.cookie_httponly = On
session.use_strict_mode = On
基本的な Docker Compose 設定を作成します。
yaml# docker-compose.yml
version: '3.8'
services:
wordpress:
build: .
container_name: wp_app
restart: unless-stopped
ports:
- '8080:80'
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_password
WORDPRESS_DB_NAME: wordpress
volumes:
- ./wordpress:/var/www/html
- ./logs:/var/log
depends_on:
mysql:
condition: service_healthy
networks:
- wordpress_network
mysql:
image: mysql:8.0
container_name: wp_mysql
restart: unless-stopped
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_password
MYSQL_ROOT_PASSWORD: root_password
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
healthcheck:
test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost']
timeout: 20s
retries: 10
networks:
- wordpress_network
volumes:
mysql_data:
networks:
wordpress_network:
driver: bridge
開発環境用 docker-compose.yml
開発環境では、開発者の利便性を重視した設定を行います。デバッグ機能やログ出力を有効にし、ファイルの変更をリアルタイムで反映できるようにします。
yaml# docker-compose.override.yml (開発環境用オーバーライド)
version: '3.8'
services:
wordpress:
environment:
# デバッグモードを有効化
WORDPRESS_DEBUG: 1
WORDPRESS_DEBUG_LOG: 1
WORDPRESS_DEBUG_DISPLAY: 1
# 開発用メール設定
WORDPRESS_CONFIG_EXTRA: |
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', true);
define('SCRIPT_DEBUG', true);
define('SAVEQUERIES', true);
// メール送信をログファイルに出力(開発環境用)
define('WP_MAIL_LOGGING', true);
volumes:
# 開発時のライブリロード用
- ./wordpress:/var/www/html
- ./themes:/var/www/html/wp-content/themes
- ./plugins:/var/www/html/wp-content/plugins
- ./config/php-dev.ini:/usr/local/etc/php/conf.d/dev.ini
ports:
- '8080:80'
# 開発用のメールキャッチャー
mailhog:
image: mailhog/mailhog:latest
container_name: wp_mailhog
ports:
- '1025:1025' # SMTP
- '8025:8025' # Web UI
networks:
- wordpress_network
# Redis キャッシュ(開発環境用)
redis:
image: redis:7.0-alpine
container_name: wp_redis
ports:
- '6379:6379'
volumes:
- redis_data:/data
networks:
- wordpress_network
# phpMyAdmin(開発環境用)
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: wp_phpmyadmin
environment:
PMA_HOST: mysql
PMA_PORT: 3306
PMA_USER: wordpress
PMA_PASSWORD: wordpress_password
ports:
- '8081:80'
depends_on:
- mysql
networks:
- wordpress_network
volumes:
redis_data:
開発環境用の PHP 設定ファイルも作成します。
ini; config/php-dev.ini - 開発環境用
; デバッグ設定
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
; Xdebug 設定(PHP 8.1用)
zend_extension=xdebug
xdebug.mode=develop,debug,coverage
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.start_with_request=yes
xdebug.log=/var/log/xdebug.log
; 開発用のメモリ設定
memory_limit = 512M
max_execution_time = 0
開発環境の起動は以下のコマンドで行います。
bash# 開発環境の起動
docker-compose up -d
# ログの確認
docker-compose logs -f wordpress
# 特定のサービスのみ再起動
docker-compose restart wordpress
図で開発環境の構成を表すと以下のようになります。
mermaidflowchart TB
dev[開発者] --> browser[ブラウザ :8080]
dev --> phpmyadmin[phpMyAdmin :8081]
dev --> mailhog[MailHog :8025]
browser --> wp[WordPress コンテナ]
wp --> mysql[MySQL コンテナ]
wp --> redis[Redis コンテナ]
wp --> mailhog_smtp[MailHog SMTP :1025]
phpmyadmin --> mysql
subgraph "開発者ツール"
phpmyadmin
mailhog
end
subgraph "WordPress アプリケーション"
wp
mysql
redis
end
本番環境用 docker-compose.yml
本番環境では、セキュリティ、パフォーマンス、監視機能を重視した設定を行います。
yaml# docker-compose.prod.yml - 本番環境用
version: '3.8'
services:
nginx:
image: nginx:alpine
container_name: wp_nginx
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./ssl:/etc/nginx/ssl
- wordpress_static:/var/www/html/wp-content
depends_on:
- wordpress
networks:
- wordpress_network
wordpress:
build:
context: .
target: production
container_name: wp_app_prod
restart: unless-stopped
environment:
# 本番環境用設定
WORDPRESS_DEBUG: 0
WORDPRESS_CONFIG_EXTRA: |
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);
define('WP_CACHE', true);
define('FORCE_SSL_ADMIN', true);
define('DISALLOW_FILE_EDIT', true);
define('AUTOMATIC_UPDATER_DISABLED', true);
volumes:
- wordpress_data:/var/www/html
- wordpress_static:/var/www/html/wp-content
- ./config/php-prod.ini:/usr/local/etc/php/conf.d/prod.ini
depends_on:
mysql:
condition: service_healthy
networks:
- wordpress_network
healthcheck:
test:
[
'CMD',
'curl',
'-f',
'http://localhost/wp-admin/install.php',
]
interval: 30s
timeout: 10s
retries: 3
mysql:
image: mysql:8.0
container_name: wp_mysql_prod
restart: unless-stopped
environment:
MYSQL_DATABASE: ${DB_NAME}
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/prod.cnf:/etc/mysql/conf.d/prod.cnf
command: --default-authentication-plugin=mysql_native_password
healthcheck:
test: ['CMD', 'mysqladmin', 'ping', '-h', 'localhost']
timeout: 20s
retries: 10
networks:
- wordpress_network
redis:
image: redis:7.0-alpine
container_name: wp_redis_prod
restart: unless-stopped
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
networks:
- wordpress_network
volumes:
wordpress_data:
wordpress_static:
mysql_data:
redis_data:
networks:
wordpress_network:
driver: bridge
本番環境用の Nginx 設定を作成します。
nginx# nginx/conf.d/wordpress.conf
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/html;
index index.php index.html;
# SSL設定
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
# セキュリティヘッダー
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# 静的ファイルのキャッシュ
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# PHP処理
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass wordpress:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# WordPress パーマリンク
location / {
try_files $uri $uri/ /index.php?$args;
}
}
データベース連携設定
データベースの設定は、パフォーマンスとセキュリティの両方を考慮する必要があります。
MySQL の本番用設定ファイルを作成します。
ini# mysql/prod.cnf - 本番環境用MySQL設定
[mysqld]
# 基本設定
default-authentication-plugin=mysql_native_password
bind-address=0.0.0.0
# パフォーマンス設定
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_flush_log_at_trx_commit=1
innodb_flush_method=O_DIRECT
# 接続設定
max_connections=200
max_allowed_packet=64M
thread_cache_size=50
# ログ設定
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow.log
long_query_time=2
# セキュリティ設定
skip-name-resolve
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem
データベース初期化用の SQL スクリプトを作成します。
sql-- mysql/init/01-init.sql
-- WordPress用データベースの初期設定
-- 文字セットの設定
ALTER DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- WordPress用ユーザーの権限設定
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER, INDEX
ON wordpress.* TO 'wordpress'@'%';
-- セキュリティ強化用設定
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;
WordPress の database.php でデータベース接続をカスタマイズできます。
php<?php
// wp-content/db.php - カスタムデータベース処理
class WP_Database_Connection {
private $connection;
public function __construct() {
$this->connect();
}
private function connect() {
$host = getenv('DB_HOST') ?: 'mysql';
$port = getenv('DB_PORT') ?: 3306;
$database = getenv('DB_NAME');
$username = getenv('DB_USER');
$password = getenv('DB_PASSWORD');
$dsn = "mysql:host={$host};port={$port};dbname={$database};charset=utf8mb4";
try {
$this->connection = new PDO($dsn, $username, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
]);
} catch (PDOException $e) {
error_log('Database connection failed: ' . $e->getMessage());
throw new Exception('Database connection failed');
}
}
}
SSL/HTTPS 対応
本番環境での SSL/HTTPS 対応は必須です。Let's Encrypt を使用した自動 SSL 証明書取得の設定を行います。
まず、SSL 証明書取得用のコンテナを追加します。
yaml# docker-compose.ssl.yml - SSL対応版
version: '3.8'
services:
certbot:
image: certbot/certbot
container_name: wp_certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
command: certonly --webroot -w /var/www/certbot --force-renewal --email admin@example.com -d example.com --agree-tos
nginx:
image: nginx:alpine
container_name: wp_nginx_ssl
restart: unless-stopped
ports:
- '80:80'
- '443:443'
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d:/etc/nginx/conf.d
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
depends_on:
- wordpress
networks:
- wordpress_network
SSL 証明書の自動更新用スクリプトを作成します。
bash#!/bin/bash
# scripts/renew-ssl.sh - SSL証明書自動更新
# 証明書の更新
docker-compose -f docker-compose.yml -f docker-compose.ssl.yml run --rm certbot renew
# Nginxの設定をリロード
docker-compose exec nginx nginx -s reload
# ログの記録
echo "SSL certificate renewal completed at $(date)" >> /var/log/ssl-renewal.log
Nginx の SSL 設定テンプレートを作成します。
nginx# nginx/templates/ssl.conf.template
server {
listen 80;
server_name ${DOMAIN_NAME};
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl http2;
server_name ${DOMAIN_NAME};
# SSL証明書の設定
ssl_certificate /etc/letsencrypt/live/${DOMAIN_NAME}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN_NAME}/privkey.pem;
# SSL最適化設定
ssl_session_timeout 1d;
ssl_session_cache shared:MozTLS:10m;
ssl_session_tickets off;
# 最新のSSL設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/html;
index index.php index.html;
# WordPress設定
include /etc/nginx/conf.d/wordpress-common.conf;
}
SSL 対応の WordPress 設定も追加します。
php<?php
// wp-config.php への追加設定
// HTTPS の強制
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
// SSL管理画面の強制
define('FORCE_SSL_ADMIN', true);
// プロキシ経由の場合のIP設定
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = trim($ips[0]);
}
図で SSL 対応の全体構成を表すと以下のようになります。
mermaidflowchart TB
user[ユーザー] --> lb[ロードバランサー/CDN]
lb --> nginx[Nginx :443]
nginx --> wp[WordPress コンテナ]
nginx --> static[静的ファイル]
wp --> mysql[MySQL コンテナ]
wp --> redis[Redis コンテナ]
certbot[Certbot] --> letsencrypt[Let's Encrypt]
letsencrypt --> ssl_cert[SSL証明書]
ssl_cert --> nginx
subgraph "SSL証明書管理"
certbot
letsencrypt
ssl_cert
end
subgraph "Webアプリケーション"
nginx
wp
static
end
subgraph "データ層"
mysql
redis
end
style ssl_cert fill:#90EE90
style nginx fill:#87CEEB
この構成により、完全に SSL 対応された WordPress 環境が構築できます。証明書の自動更新機能により、運用負荷も大幅に軽減されます。
まとめ
Docker を活用した WordPress 環境の構築により、従来の課題を根本的に解決できることをご紹介しました。
開発・本番環境の差分をなくすことで、「私の環境では動く」問題や予期しないデプロイエラーが劇的に減少します。Docker Compose による統一された環境定義により、新しいチームメンバーでも数分で開発環境を立ち上げることができます。
マルチステージビルドによって、開発時の利便性と本番時の効率性を両立できました。環境変数を活用した設定管理により、機密情報を安全に管理しながら、同一のコードで複数の環境に対応可能です。
特に重要なポイントとして、以下の図で示すような運用フローが確立できます。
mermaidflowchart LR
dev_code[開発コード] --> git[Git Repository]
git --> ci[CI/CD Pipeline]
ci --> test[自動テスト]
test --> build[Docker Build]
build --> registry[Container Registry]
registry --> staging[ステージング環境]
staging --> prod[本番環境]
subgraph "品質保証"
test
staging
end
subgraph "デプロイメント"
build
registry
prod
end
style test fill:#90EE90
style staging fill:#87CEEB
style prod fill:#FFB6C1
このワークフローにより、コードの品質を保ちながら、迅速で確実なデプロイが実現できます。
Docker による WordPress 環境構築は、初期の学習コストはありますが、中長期的には開発効率の大幅な向上とトラブルの減少をもたらします。環境差分による問題で悩んでいる方は、ぜひ今回ご紹介した方法を試してみてください。
継続的な改善により、より安定で効率的な WordPress 開発環境を構築できるでしょう。
関連リンク
- article
WordPress を Docker で最速構築:開発/本番の環境差分をなくす手順
- article
WordPress 技術ロードマップ 2025:ブロック × ヘッドレス二刀流の最前線
- article
WordPress のインストール完全手順:レンタルサーバー・Docker・ローカルを徹底比較
- article
WordPress 入門:5 分で立ち上げる最新サイト構築ガイド
- article
「WordPress」ログインしていないユーザへのリダイレクトや自動ログインなど処理いろいろ
- article
WordPress を Docker で最速構築:開発/本番の環境差分をなくす手順
- article
Docker の全体像を俯瞰:コンテナ時代の開発・配布・運用を一本化する戦略ガイド
- article
Docker Swarm 徹底入門:Kubernetes に移行する前に理解すべきこと
- article
Playwright × Docker:本番環境に近い E2E テストを構築
- article
Docker でマイクロサービスを構築するアーキテクチャ入門
- article
Vite × Docker:本番運用を見据えたコンテナ化手順
- article
【比較検証】Convex vs Firebase vs Supabase:リアルタイム性・整合性・学習コストの最適解
- article
【徹底比較】Preact vs React 2025:バンドル・FPS・メモリ・DX を総合評価
- article
GPT-5-Codex vs Claude Code / Cursor 徹底比較:得意領域・精度・開発速度の違いを検証
- article
Astro × Cloudflare Workers/Pages:エッジ配信で超高速なサイトを構築
- article
【2025 年版】Playwright vs Cypress vs Selenium 徹底比較:速度・安定性・学習コストの最適解
- article
Apollo を最短導入:Vite/Next.js/Remix での初期配線テンプレ集
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来