DockerでWordpress構築

# 前回の振り返り


前回は1台のコンテナを単体で構築しました。
今回は複数のコンテナを連携させて動作させたいと思います。

前回の記事
https://qiita.com/miyamon_key/items/35bdd2048c7ff73b64ba

# 私の環境情報

PC:windows 11
Docker Desktop:4.33.1
Terminal:VScodeのGit bash

# ディレクトリ構成

```
│      └─dev
│          │  .env
│          │  docker-compose.yml
│          │
│          └─dockerfiles
│              ├─mysql
│              │      Dockerfile
│              │      my.cnf
│              └─wordpress
│                      apache2.conf
│                      dev-wordpress.me.conf
│                      Dockerfile

```

.envファイルに環境変数を書き
docker-compose.ymlでDBのパスワード等の機密情報を読み込むようにしています。
機密情報を環境変数として管理する事で、githubで管理する場合に「.gitignore」に入れることで機密情報の公開を避けることが出来ます。

それでは次に各ファイルの中身に踏み込んでいきます。

## docker-compose.yml
```
services:
  db:
    build:
      context: .
      dockerfile: ./dockerfiles/mysql/Dockerfile
    container_name: mysql
    hostname: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    networks:
      - dev-network

  wordpress:
    build:
      context: .
      dockerfile: ./dockerfiles/wordpress/Dockerfile
    container_name: wordpress
    hostname: wordpress
    restart: always
    depends_on:
      - db
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: mysql:3306
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
      WORDPRESS_DEBUG: 1
    volumes:
      - ./www:/var/www/wordpress
    networks:
      - dev-network

networks:
  dev-network:
    driver: bridge


```

### <ファイル構成の解説>

- `networks`の定義
同じ内部ネットワークにコンテナが位置していると相互に通信することができます。
そのため明示的にdev-networkに属すことをdocker-composeでは記載しています。
そして`bridge`というのがDockerのデフォルトのネットワークドライバのようなのですが、明示的にnetworksを定義しなかった場合も`bridge`にコンテナは属してくれるので、コンテナ間通信は出来るようです。
ただし細かい制御を聞かせたい場合は `networks`の定義は重要なので、定義を癖づけるためにも定義するようにしました。

## mysql/Dockerfile

```
FROM mysql:8

# my.cnfをコンテナの/etcディレクトリに配置
COPY ./dockerfiles/mysql/my.cnf /etc/

```
### <ファイル構成の解説>
mysqlのDockerfileには多くは書いていません。
`COPY`モジュールを利用してmysqlの設定ファイルを管理するようにしています。
この設定ファイルをコピーして管理する方法は、ansibleなどの構成管理ツールでもよく利用する方法なので覚えておくと他の技術でも役立つように思います。

## mysql/my.cnf
```
[mysqld]
character-set-server=utf8mb4 #文字コードutf8mb4の指定
default-time-zone = 'Asia/Tokyo'
host-cache-size=0
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/run/mysqld/mysqld.sock
secure-file-priv=/var/lib/mysql-files
user=mysql

pid-file=/var/run/mysqld/mysqld.pid
[client]
default-character-set=utf8mb4
socket=/var/run/mysqld/mysqld.sock

!includedir /etc/mysql/conf.d/
```
my.cnfに関しては多くは設定しておらず、timezoneやcharacter-setのみカスタマイズしました。

## wordpress/Dockerfile
```
FROM wordpress:php8.1-apache
COPY ./dockerfiles/wordpress/apache2.conf /etc/apache2/
COPY ./dockerfiles/wordpress/dev-wordpress.me.conf /etc/apache2/sites-enabled/

RUN a2enmod proxy proxy_http && \
    service apache2 restart
EXPOSE 80

```
### <ファイル構成の解説>
apacheもCOPYモジュールで設定を管理しています。


## wordpress/apache2.conf
```
DefaultRuntimeDir ${APACHE_RUN_DIR}
PidFile ${APACHE_PID_FILE}
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
HostnameLookups Off
ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Include list of ports to listen on
Include ports.conf
<Directory />
        Options FollowSymLinks
        AllowOverride None
        Require all denied
</Directory>

<Directory /usr/share>
        AllowOverride None
        Require all granted
</Directory>

<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
</Directory>
AccessFileName .htaccess
<FilesMatch "^\.ht">
        Require all denied
</FilesMatch>
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%a %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf

```
## wordpress/dev-wordpress.me.conf
```
<VirtualHost *:80>
  ServerName dev-wordpress.me
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/wordpress

  # リバースプロキシ設定
  ProxyPass / http://localhost/
  ProxyPassReverse / http://localhost/

  # ログ設定
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

```

# 動作確認

`docker-compose up -d`はイメージ空コンテナを起動するコマンドですが最後に起動結果が表れます。
以下のように`Running 2/2`となることが一つの成功基準だと思っています。
```
docker-compose up -d
[+] Running 2/2
 ✔ Container mysql      Started                                                                                                     0.9s 
 ✔ Container wordpress  Started   
```

次はコンテナのステータス確認ですが、起動(UP)していそうです。

```
$ docker ps -a
CONTAINER ID   IMAGE           COMMAND                   CREATED          STATUS          PORTS                 NAMES
c0146ba7dc59   dev-wordpress   "docker-entrypoint.s…"   15 seconds ago   Up 14 seconds   0.0.0.0:80->80/tcp    wordpress
605d2c0b08f9   dev-db          "docker-entrypoint.s…"   15 seconds ago   Up 15 seconds   3306/tcp, 33060/tcp   mysql
```




試しにコンテナにログインすることもできました。
apacheのconfファイルで指定していたrootディレクトリに移動出来てwordpressのソースファイルもあります。
```
$ docker exec -it wordpress bash
root@wordpress:/var/www/html# 
root@wordpress:/var/www/html# ls -al
total 264
drwxr-xr-x  5 www-data www-data  4096 Oct  8 15:21 .
drwxr-xr-x  1 root     root      4096 Oct  8 15:21 ..
-rw-r--r--  1 www-data www-data   261 Oct  1 22:22 .htaccess
-rw-r--r--  1 www-data www-data   405 Feb  6  2020 index.php
-rw-r--r--  1 www-data www-data 19915 Jan  1  2024 license.txt
-rw-r--r--  1 www-data www-data  7409 Jun 18 11:59 readme.html
<省略>
```


最後にブラウザでアクセス確認しても最初のwordpress設定画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576311/64125cac-abc7-083d-74cb-75751b19e05b.png)

そしてここから言語を選択してwordpressをインストールするのですが
コンテナは一度起動停止すると、中のデータが消えてしまします。。。このおかげで軽量で扱えているのですが。。。
つまり起動する度にこの言語選択やユーザ名、パスワードが必要になります。
しかし安心してください。
これを防ぐために`volumes:`という設定があります。
これはコンテナが停止してもデータを保持してくれる仮想のストレージを作る設定なのですが、主にプログラムのソースコードや、コンテナ間通信で利用するsocketファイルなどに私は利用しています。

この機能については、現在laravel開発環境をdockerで構築検証しており、絶賛`volumes:`を利用してソースコード管理していますので、そのレポートとして今度の記事に書こうと思います。

以上ありがとうございました。