WordpressをDockerで運用する方法

## 1. はじめに

この記事では、Dockerを活用してWordPress環境を構築し、Apacheをリバースプロキシとして利用したSSL対応のWordPressサイトの作り方をご紹介します。ホスト上のApacheでSSL証明書を管理し、コンテナ化されたWordPressとMySQLを組み合わせることで、安全で扱いやすいWebサイト環境を実現できます。
(現在運用中のWikiにも同様の記事を掲載していますが、今後Wikiを閉鎖する可能性があるため、Qiitaへ移行)

## 2. 対象読者

- Dockerの基本的な知識を持っている方
- WordPressをDockerで運用したい方
- Apacheをリバースプロキシとして活用したい方
- CentOS環境でサーバーを運用している方

## 3. 目次
- [1. はじめに](#1-はじめに)
- [2. 対象読者](#2-対象読者)
- [3. 目次](#3-目次)
- [4. 環境](#4-環境)
- [5. 本編](#5-本編)
  - [環境構築](#環境構築)
    - [構成](#構成)
    - [方針](#方針)
    - [サブドメイン登録](#サブドメイン登録)
    - [SSL証明書の発行](#ssl証明書の発行)
    - [Apacheの設定](#apacheの設定)
    - [docker-compose.yml の作成](#docker-composeyml-の作成)
    - [コンテナ作成](#コンテナ作成)
- [6. さいごに](#6-さいごに)
- [7. 参考サイト](#7-参考サイト)

## 4. 環境

本記事では、以下の環境を前提としています：

- CentOS Stream 9 (ホスト環境)
- Apache 2.4.53 (ホストにインストール済み)
- Let's Encrypt (SSL証明書として利用)
- HTTPS通信が可能な環境
- グローバルIPアドレスに関連付けされたドメイン名
- Docker 20.10.21

## 5. 本編

### 環境構築

#### 構成

以下の図は、今回構築するシステムの全体構成です。クライアントからのリクエストはホストのApacheで受け、WordPressコンテナに転送され、データベース操作はMySQLコンテナで行われます。

```mermaid
graph LR
    A[クライアント] --> B[ホストのApache]
    B --> C[WordPressコンテナ]
    C <--> D[MySQLコンテナ]
```

#### 方針

今回の構築では、以下の方針で進めていきます：

1. WordPress用に新しくサブドメインを登録します
2. そのサブドメインへのアクセスを、Apacheに設定したリバースプロキシでWordPressコンテナに転送します
3. SSL証明書はホスト上のApacheで設定し、安全な通信を確保します

#### サブドメイン登録

まず、WordPressサイト用のサブドメインを登録します。

以下では「abc.example.com」を例として説明します。実際の環境では、お持ちのドメインに置き換えてください。

#### SSL証明書の発行

Let's Encryptを使用してSSL証明書を発行します。以下のコマンドを実行してください：

```
$ certbot certonly --webroot -w <ドキュメントルート> -d abc.example.com
```

`<ドキュメントルート>`には、実際のWebサーバーのドキュメントルートパスを指定します。

#### Apacheの設定

SSL通信とリバースプロキシを設定するため、Apache設定ファイルを編集します。「/etc/httpd/conf.d/ssl.conf」に以下の内容を追記してください：

```
<VirtualHost abc.example.com:443>
   ServerName abc.example.com
   SSLEngine on
   SSLProtocol all
   SSLCertificateFile <証明書の絶対パス>/cert.pem
   SSLCertificateKeyFile <証明書の絶対パス>/privkey.pem
   SSLCertificateChainFile <証明書の絶対パス>/chain.pem

   ProxyPreserveHost On
   ProxyPass / http://localhost:8082/
   ProxyPassReverse / http://localhost:8082/
   RequestHeader set X-Forwarded-Proto "https" # ※1
   RequestHeader set X-Forwarded-Port "443"    # ※1
</VirtualHost>

# ※1. この設定がないと、混在コンテンツとなりJavaScriptやCSSなどが正常に読み込まれません
```

`<証明書の絶対パス>`には、Let's Encryptが生成した証明書ファイルの実際のパスを指定します。

設定ファイルを編集後、Apacheを再起動します：

```
$ sudo systemctl restart httpd
```

#### docker-compose.yml の作成

次に、WordPressとMySQLのコンテナを定義するための設定ファイルを作成します。任意のディレクトリに「docker-compose.yml」という名前で以下の内容を保存してください：

```
version: '3'
services:
  wordpress:
    image: wordpress:php8.0-apache
    container_name: wordpress
    ports:
      - 8082:80
    volumes:
      - ./wp-data:/var/www/html
    environment:
      WORDPRESS_DB_HOST: wordpress-db
      WORDPRESS_DB_USER: <ユーザ名>
      WORDPRESS_DB_PASSWORD: <パスワード>
      WORDPRESS_DB_NAME: <DB名>
    depends_on:
      - wordpress-db
    restart: always

  wordpress-db:
    image: mysql:8.0
    container_name: wordpress-db
    ports:
      - 3308:3306
    environment:
      TZ: Asia/Tokyo
      MYSQL_ROOT_PASSWORD: <ルートパスワード>
      MYSQL_DATABASE: <DB名>
      MYSQL_USER: <ユーザ名>
      MYSQL_PASSWORD: <パスワード>
    volumes:
      - ./db-data:/var/lib/mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    restart: always
```

`<ユーザ名>`、`<パスワード>`、`<DB名>`、`<ルートパスワード>`は、実際の値に置き換えてください。

#### コンテナ作成

最後に、以下のコマンドを実行してコンテナを作成・起動します：

```
$ docker-compose up -d
```

コマンド実行後、WordPressとMySQLの接続が確立されるまで数十秒かかることがあります。

すべての設定が完了したら、ブラウザで「https://abc.example.com」にアクセスしてください。WordPressのインストール画面が表示されれば成功です。

## 6. さいごに

本記事では、DockerとApacheを組み合わせてSSL対応のWordPress環境を構築する方法を解説しました。この構成では、Apacheがリバースプロキシとして機能し、SSL通信の終端となるため、コンテナ内のWordPressアプリケーションはHTTPのみを扱えばよく、設定がシンプルになります。

また、Docker化することで環境の再現性が高まり、バックアップやアップデートも容易になります。この方法を応用すれば、他のWebアプリケーションも同様に構築できるでしょう。

## 7. 参考サイト

- [Dockerを使ってサクッとHTTPS対応WordPress環境を構築する | 気さくなエンジニ屋](https://4mo.co/start-wordpress-with-docker/#check-container-log)
- [Apacheでマルチドメイン証明書で複数のSSLサイトを構成する](https://ssl-process.com/support/etc/apache_multidomain/index.php)
- [proxies - Reverse proxy and auto_complete with mixed content - Drupal Answers](https://drupal.stackexchange.com/questions/309701/reverse-proxy-and-auto-complete-with-mixed-content)