WordPressをDocker化してAWSにデプロイする方法

WordPressをDockerコンテナ化してAWSにデプロイすることで、スケーラブルで管理しやすいWebサイト環境を構築できます。この記事では、WordPressのDockerコンテナ化からAWSへのデプロイまでの手順を詳しく解説します。

目次

  1. Docker化のメリット
  2. 前提条件
  3. WordPressのDockerコンテナ化
  4. AWS環境の準備
  5. AWS ECSへのデプロイ
  6. AWS Fargateを使ったサーバーレスデプロイ
  7. セキュリティとパフォーマンスの最適化
  8. 運用管理のポイント
  9. まとめ

Docker化のメリット

WordPressをDockerコンテナ化することには、以下のようなメリットがあります:

  • 環境の一貫性: 開発・テスト・本番環境での一貫性の確保
  • 簡単なスケーリング: 負荷に応じて簡単にスケールアウト可能
  • 移植性: クラウドプロバイダーを問わず同じ構成で展開可能
  • バージョン管理: WordPressとPHPのバージョンを明示的に管理可能
  • 分離: 他のアプリケーションと依存関係を分離

前提条件

  • Dockerの基本的な知識
  • AWSアカウント
  • AWS CLIのインストールと設定
  • 基本的なLinuxコマンドの知識

WordPressのDockerコンテナ化

1. プロジェクト構造の作成

まず、プロジェクトのディレクトリ構造を作成します:

mkdir -p wordpress-docker/php
cd wordpress-docker

2. docker-compose.yml ファイルの作成

ローカル開発環境用のDocker Compose設定を作成します:

version: '3'

services:
  wordpress:
    image: wordpress:6.4.2-php8.2-apache
    restart: always
    depends_on:
      - db
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_password
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - ./wordpress:/var/www/html
      - ./php/custom.ini:/usr/local/etc/php/conf.d/custom.ini
    networks:
      - wordpress-network

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_password
      MYSQL_ROOT_PASSWORD: root_password
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - wordpress-network

volumes:
  mysql-data:

networks:
  wordpress-network:

3. カスタムPHP設定の作成

必要に応じてPHPの設定をカスタマイズします:

cat > php/custom.ini << EOF
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
memory_limit = 256M
EOF

4. Dockerfileの作成

本番環境用のカスタムイメージを作成する場合は、Dockerfileを作成します:

FROM wordpress:6.4.2-php8.2-apache

# PHPの設定をコピー
COPY php/custom.ini /usr/local/etc/php/conf.d/custom.ini

# 必要なPHP拡張機能をインストール
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    libwebp-dev \
    && docker-php-ext-configure gd --with-jpeg --with-webp \
    && docker-php-ext-install gd mysqli pdo pdo_mysql

# WordPressの推奨設定
RUN a2enmod rewrite expires

# 権限設定
RUN chown -R www-data:www-data /var/www/html

# ヘルスチェック用のスクリプト
COPY healthcheck.php /var/www/html/

EXPOSE 80

CMD ["apache2-foreground"]

5. ヘルスチェックファイルの作成

コンテナのヘルスチェック用のPHPファイルを作成します:

cat > healthcheck.php << EOF
<?php
// データベース接続をチェック
\$host = getenv('WORDPRESS_DB_HOST');
\$user = getenv('WORDPRESS_DB_USER');
\$pass = getenv('WORDPRESS_DB_PASSWORD');
\$name = getenv('WORDPRESS_DB_NAME');

try {
    \$conn = new mysqli(explode(':', \$host)[0], \$user, \$pass, \$name);
    if (\$conn->connect_error) {
        http_response_code(500);
        die("データベース接続エラー: " . \$conn->connect_error);
    }
    echo "WordPress環境は正常に動作しています";
} catch (Exception \$e) {
    http_response_code(500);
    die("エラー: " . \$e->getMessage());
}
?>
EOF

6. イメージのビルドとテスト

ローカル環境で動作確認します:

docker-compose up -d

ブラウザで http://localhost:8080 にアクセスし、WordPressのインストール画面が表示されることを確認します。

7. 本番用イメージのビルドとタグ付け

docker build -t my-wordpress:latest .

AWS環境の準備

1. ECRリポジトリの作成

AWSのElastic Container Registry (ECR)にリポジトリを作成します:

aws ecr create-repository --repository-name my-wordpress

2. イメージのプッシュ

ビルドしたイメージをECRにプッシュします:

# ECRへのログイン
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com

# イメージにタグ付け
docker tag my-wordpress:latest <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/my-wordpress:latest

# イメージのプッシュ
docker push <アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/my-wordpress:latest

3. RDSデータベースの作成

WordPressのデータを保存するためのMySQLデータベースをRDSで作成します:

aws rds create-db-instance \
    --db-instance-identifier wordpress-db \
    --db-instance-class db.t3.micro \
    --engine mysql \
    --engine-version 8.0 \
    --allocated-storage 20 \
    --master-username wordpress \
    --master-user-password <安全なパスワード> \
    --db-name wordpress \
    --vpc-security-group-ids <セキュリティグループID> \
    --db-subnet-group-name <サブネットグループ名> \
    --backup-retention-period 7 \
    --no-publicly-accessible

4. AWS Secrets Managerの設定

データベース接続情報を安全に管理するためにSecrets Managerを使用します:

aws secretsmanager create-secret \
    --name wordpress/db-credentials \
    --description "WordPress database connection details" \
    --secret-string "{\"username\":\"wordpress\",\"password\":\"<安全なパスワード>\",\"engine\":\"mysql\",\"host\":\"<RDSエンドポイント>\",\"port\":3306,\"dbname\":\"wordpress\"}"

AWS ECSへのデプロイ

1. ECSクラスターの作成

aws ecs create-cluster --cluster-name wordpress-cluster

2. タスク定義の作成

task-definition.jsonファイルを作成します:

{
  "family": "wordpress-task",
  "networkMode": "awsvpc",
  "executionRoleArn": "arn:aws:iam::<アカウントID>:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::<アカウントID>:role/ecsWordPressTaskRole",
  "containerDefinitions": [
    {
      "name": "wordpress",
      "image": "<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/my-wordpress:latest",
      "essential": true,
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 80,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "WORDPRESS_DB_NAME",
          "value": "wordpress"
        }
      ],
      "secrets": [
        {
          "name": "WORDPRESS_DB_USER",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:<アカウントID>:secret:wordpress/db-credentials:username::"
        },
        {
          "name": "WORDPRESS_DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:<アカウントID>:secret:wordpress/db-credentials:password::"
        },
        {
          "name": "WORDPRESS_DB_HOST",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:<アカウントID>:secret:wordpress/db-credentials:host::"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/wordpress",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "wordpress"
        }
      },
      "healthCheck": {
        "command": [
          "CMD-SHELL",
          "curl -f http://localhost/healthcheck.php || exit 1"
        ],
        "interval": 30,
        "timeout": 5,
        "retries": 3,
        "startPeriod": 60
      },
      "mountPoints": [
        {
          "sourceVolume": "wordpress-content",
          "containerPath": "/var/www/html/wp-content",
          "readOnly": false
        }
      ]
    }
  ],
  "volumes": [
    {
      "name": "wordpress-content",
      "efsVolumeConfiguration": {
        "fileSystemId": "<EFSファイルシステムID>",
        "transitEncryption": "ENABLED",
        "authorizationConfig": {
          "accessPointId": "<EFSアクセスポイントID>"
        }
      }
    }
  ],
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "1024",
  "memory": "2048"
}

タスク定義を登録します:

aws ecs register-task-definition --cli-input-json file://task-definition.json

3. EFSファイルシステムの作成

WordPressのコンテンツを永続化するためのEFSを作成します:

aws efs create-file-system \
    --performance-mode generalPurpose \
    --throughput-mode bursting \
    --encrypted \
    --tags Key=Name,Value=wordpress-content

# アクセスポイントの作成
aws efs create-access-point \
    --file-system-id <ファイルシステムID> \
    --posix-user Uid=33,Gid=33 \
    --root-directory Path=/wp-content,CreationInfo='{OwnerUid=33,OwnerGid=33,Permissions=0755}'

4. サービスの作成

aws ecs create-service \
    --cluster wordpress-cluster \
    --service-name wordpress-service \
    --task-definition wordpress-task \
    --desired-count 2 \
    --launch-type FARGATE \
    --network-configuration "awsvpcConfiguration={subnets=[<サブネットID1>,<サブネットID2>],securityGroups=[<セキュリティグループID>],assignPublicIp=ENABLED}" \
    --load-balancers "targetGroupArn=<ターゲットグループARN>,containerName=wordpress,containerPort=80" \
    --health-check-grace-period-seconds 120 \
    --deployment-configuration "maximumPercent=200,minimumHealthyPercent=100,deploymentCircuitBreaker={enable=true,rollback=true}" \
    --enable-execute-command

AWS Fargateを使ったサーバーレスデプロイ

前述の手順では既にFargateを利用するタスク定義とサービスを作成しましたが、Fargateを効果的に活用するためのポイントを解説します。

1. Auto Scalingの設定

コンテナのCPUやメモリ使用率に基づいて自動的にスケールするように設定します:

# サービスのAuto Scalingターゲットを登録
aws application-autoscaling register-scalable-target \
    --service-namespace ecs \
    --scalable-dimension ecs:service:DesiredCount \
    --resource-id service/wordpress-cluster/wordpress-service \
    --min-capacity 2 \
    --max-capacity 10

# CPU使用率に基づくスケーリングポリシーを設定
aws application-autoscaling put-scaling-policy \
    --policy-name wordpress-cpu-scaling \
    --service-namespace ecs \
    --scalable-dimension ecs:service:DesiredCount \
    --resource-id service/wordpress-cluster/wordpress-service \
    --policy-type TargetTrackingScaling \
    --target-tracking-scaling-policy-configuration file://scaling-policy.json

scaling-policy.jsonの内容:

{
  "TargetValue": 70.0,
  "PredefinedMetricSpecification": {
    "PredefinedMetricType": "ECSServiceAverageCPUUtilization"
  },
  "ScaleOutCooldown": 60,
  "ScaleInCooldown": 300
}

2. アプリケーションロードバランサーの設定

複数のFargateタスク間でトラフィックを分散させるALBを設定します:

# ロードバランサーの作成
aws elbv2 create-load-balancer \
    --name wordpress-alb \
    --subnets <サブネットID1> <サブネットID2> \
    --security-groups <セキュリティグループID> \
    --scheme internet-facing \
    --type application

# ターゲットグループの作成
aws elbv2 create-target-group \
    --name wordpress-tg \
    --protocol HTTP \
    --port 80 \
    --vpc-id <VPC ID> \
    --target-type ip \
    --health-check-path /healthcheck.php \
    --health-check-interval-seconds 30

# リスナーの作成
aws elbv2 create-listener \
    --load-balancer-arn <ロードバランサーARN> \
    --protocol HTTP \
    --port 80 \
    --default-actions Type=forward,TargetGroupArn=<ターゲットグループARN>

セキュリティとパフォーマンスの最適化

1. WAFの設定

WordPressサイトを保護するためにAWS WAF(Web Application Firewall)を設定します:

# WAF WebACLの作成
aws wafv2 create-web-acl \
    --name wordpress-protection \
    --scope REGIONAL \
    --default-action Allow={} \
    --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=wordpress-protection \
    --rules file://waf-rules.json \
    --region ap-northeast-1

waf-rules.jsonの例:

[
  {
    "Name": "AWSManagedRulesCommonRuleSet",
    "Priority": 0,
    "Statement": {
      "ManagedRuleGroupStatement": {
        "VendorName": "AWS",
        "Name": "AWSManagedRulesCommonRuleSet"
      }
    },
    "OverrideAction": {
      "None": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "AWSManagedRulesCommonRuleSet"
    }
  },
  {
    "Name": "AWSManagedRulesWordPressRuleSet",
    "Priority": 1,
    "Statement": {
      "ManagedRuleGroupStatement": {
        "VendorName": "AWS",
        "Name": "AWSManagedRulesWordPressRuleSet"
      }
    },
    "OverrideAction": {
      "None": {}
    },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "AWSManagedRulesWordPressRuleSet"
    }
  }
]

2. CloudFrontの設定

コンテンツ配信を高速化し、ALBの負荷を軽減するためにCloudFrontを設定します:

aws cloudfront create-distribution \
    --origin-domain-name <ALBのDNS名> \
    --default-cache-behavior CachePolicyId=658327ea-f89d-4fab-a63d-7e88639e58f6,TargetOriginId=wordpress-alb,ViewerProtocolPolicy=redirect-to-https \
    --enabled \
    --comment "WordPress distribution"

3. Secrets Managerを使った機密情報の管理

WordPressの設定ファイルに直接認証情報を記載せず、Secrets Managerから取得するスクリプトを作成:

<?php
// wp-config.php内に追加するコード
require_once(ABSPATH . 'wp-secrets.php');

// wp-secrets.php
<?php
if (getenv('WORDPRESS_DB_HOST') && getenv('WORDPRESS_DB_USER') && getenv('WORDPRESS_DB_PASSWORD')) {
    define('DB_HOST', getenv('WORDPRESS_DB_HOST'));
    define('DB_USER', getenv('WORDPRESS_DB_USER'));
    define('DB_PASSWORD', getenv('WORDPRESS_DB_PASSWORD'));
    define('DB_NAME', getenv('WORDPRESS_DB_NAME'));
}

運用管理のポイント

1. バックアップ戦略

WordPress環境の効果的なバックアップ戦略を実装します:

  1. RDSの自動バックアップ:毎日のスナップショットと特定のポイントへの復元機能を有効化
  2. EFSのバックアップ:AWS Backupを使用してEFSのバックアップを設定
  3. コンテンツのエクスポート:定期的なWordPressコンテンツのエクスポート
# AWS Backupの設定例
aws backup create-backup-plan \
    --backup-plan file://backup-plan.json

2. モニタリングとアラート

CloudWatchを活用したモニタリングとアラートを設定します:

# CPUアラームの設定例
aws cloudwatch put-metric-alarm \
    --alarm-name WordPress-High-CPU \
    --comparison-operator GreaterThanThreshold \
    --evaluation-periods 2 \
    --metric-name CPUUtilization \
    --namespace AWS/ECS \
    --period 300 \
    --statistic Average \
    --threshold 80 \
    --alarm-description "Alarm when CPU exceeds 80%" \
    --dimensions Name=ClusterName,Value=wordpress-cluster Name=ServiceName,Value=wordpress-service \
    --alarm-actions <SNSトピックARN>

3. 自動デプロイパイプラインの構築

CI/CDパイプラインを構築して、コードの変更が自動的にデプロイされるようにします:

# CodePipelineの作成例
aws codepipeline create-pipeline \
    --pipeline file://wordpress-pipeline.json

まとめ

WordPressをDockerコンテナ化してAWSにデプロイすることで、以下のメリットが得られます:

  1. スケーラビリティ: トラフィック増加に応じて自動的にスケールアウト
  2. 高可用性: 複数のAZにまたがるデプロイメントによる高可用性の実現
  3. セキュリティ: AWSWAF、Secrets Manager、暗号化などによるセキュリティ強化
  4. パフォーマンス: CloudFrontによるコンテンツ配信の高速化
  5. コスト効率: 実際の負荷に応じたリソース割り当て
  6. 運用効率: インフラ管理の自動化と効率化

この記事で説明した方法を活用して、堅牢でスケーラブルなWordPress環境をAWS上に構築してください。環境に合わせてカスタマイズし、継続的に改善していくことで、より効率的なWordPress運用が可能になります。

コメント

タイトルとURLをコピーしました