Wordpress公式のwordpress:cliイメージを使う

# やりたいこと

Wordpressの公式コンテナを使い、Docker-composeでWPサイトを作成すると、最初にアクセスしたときに言語やサイト名、管理ユーザー名などの初期設定の画面が表示される。これらの設定も設定済みの状態にするような方法がないかというと（環境変数とかでできてもよさそうだが・・・）WordpressのCLI管理ソフトを利用してスクリプト化しておくのがいいのじゃないかという結論に至った。

[library/wordpress - Docker Hub](https://hub.docker.com/_/wordpress/)


wp-cliも上記の公式にイメージが用意されており（一番下の方）、WP本体のボリュームをマウントすることで利用できる作りになっているようだが、いくつかのタスクが、具体的には日本語の定義ファイルをDLインストールするところがうまくいかなかったのでその原因を調べてみた。


# やったこと（うまくいかない現象）

## Wordpressを立てる

まずは、Wordpressを普通に立てる。これはいろんな記事があり、mysqlとセットであげるようなdocker-composeを作るのが簡単。

[DockerでWordPress環境を構築する - Qiita](https://qiita.com/bwtakacy/items/58df8839ef6770eafd5b) より引用すると

```docker-compose.yml
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - dbdata:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    dbdata:
```
## wordpress:cliでアクセスする

これに対して、WP-CLIでアクセスして、設定などを行えるようにする。
wp-cliは、ssh越しやHTTP越しでも出来るようだが、Docker環境化ならば、`--volumes-from`で、Wordpressコンテナのインストール先をマウントして、そこで処理するという方法を取れる。

```既存のコンテナに接続してwp-cliを使用するコマンド
docker run -it --rm \
    --volumes-from some-wordpress \
    --network container:some-wordpress \
    wordpress:cli  <WP-CLIのサブコマンド>
```

と、ここまでが、ほぼ公式通りのインタラクションと思われる。

## うまくいかない。

上記のWP-CLIを利用するためのコマンドを、長いので`DOCKER_WP_CLI`とエイリアスしたとして、いくつかのコマンドがうまくいかない。

```bash:うまくいかない

# install core 
$ DOCKER_WP_CLI core install --url="https://something.example.com" \
                --title="Wordpress blog" \
                --admin_user="adminadmin" \
                --admin_email="adminadmin@example.com"

Admin password: xxxxxxxx
Warning: Unable to create directory wp-content/uploads/2018/04. Is its parent directory writable by the server?
Success: WordPress installed successfully.

# install Japanese language definition
$ DOCKER_WP_CLI language core install ja
$ DOCKER_WP_CLI language core activate ja

Error: Could not create directory. "/var/www/html/wp-content/languages/"
Error: Language not installed.
```
日本語化が上手く言ってない。
コアの方も一件すると上手くいってそうとおもったが、Warningにあるようにメディアアップロード用のディレクトリが作れていないようだ。

# 原因

結論から言うと、「WPのコンテナと、WP-CLIのコンテナでwww-dataユーザーのuidが違った」ことが原因のようだ。これはWP本体のImageがDebianで作られており、wp-cliのほうはAlpineベースのため、起きていると思われる。

```bash:WP本体の方のコンテナ
$ cat /etc/passwd | grep www-data
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
(略)
```
↑ www-dataはUIDが33 ↓ UIDが82

```bash:WP-CLIのコンテナ
$ cat /etc/passwd | grep www-data
www-data:x:82:82:Linux User,,,:/home/www-data:/bin/false

$ cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
(略)
```


# 解決方法

WPのほうもAlpineベースのコンテナを選択することで、ちゃんと動くようになる。

ところが、Alpineベースのものは、php-fpmを用いたものしかないようで、Webサーバーは同梱されていない。
なので、別途nginxのコンテナを立ててやる必要がある。

- 参考
  - [nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する - Qiita](https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)
  - [docker-composeでWordpress + MariaDB + nginx環境を構築する | anopara](https://anopara.net/2017/12/20/docker-compose%E3%81%A7wordpress-mariadb-nginx%E7%92%B0%E5%A2%83%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B/)


内容としては上記のそのままだが、まとめると、

```docker-compose.yml
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - dbdata:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image:  wordpress:4.9.4-php7.2-fpm-alpine # Alpineにする！
     volumes:
       - wpdata:/var/www/html
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress

  nginx:
    image: nginx
    ports:
      - 80:80
    volumes:
      - ./nginx_build/nginx.conf:/etc/nginx/nginx.conf
      - wpdata:/var/www/html

volumes:
    dbdata:
    wpdata:

```

```conf:./ngnx_build/nginx.conf（抜粋）
server {
    listen 80;
    server_name something.example.com;
 
    root /var/www/html;
    index index.php;
 
    access_log /var/log/nginx/hoge.log;
    error_log /var/log/nginx/hoge.log;
 
    location / {
        try_files $uri $uri/ /index.php?$args;
    }
 
    location ~ \.php$ {
        try_files $uri =404;
        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;
    }
}
```

このように設定する。
こうすると、WP本体もWP-CLIもAlpineになったので、前述の`wordpress:cli`のコンテナの使い方で上手く行くことが確認できた。

WP本体側とwp-cli側両方を最短手番で調べると、引っかかる問題なので、ほかにも困っている人がいたら助けになるといいなー。

# 解決方法2

DebianのWPのほうでwww-dataのuidは33で、wp-cliのでそのuidを持っているのはxfsというユーザーだった。
なので、そのユーザー名でログインするようにしてやれば、一応動く。

```bash
$ docker run -it --rm \
    --volumes-from some-wordpress \
    --network container:some-wordpress \
    -u xfs \
    wordpress:cli core install ja

Downloading translation from https://downloads.wordpress.org/translation/core/4.9.4/ja.zip...
Unpacking the update...
Installing the latest version...

```

動くけどなにか気持ち悪い。

# 補足

ちなみに、最初、WPの本体をインストールしたときに、言語設定のが面が出ずにいきなり英語で設定が始まる場合があると思います。その場合はproxy設定などでささってないか確認すると良いです。言語設定ファイルとかがそもそもダウンロードできない状況だと英語で設定を始めるっぽい。

proxyめ・・・。