あるSEのつぶやき・改

ITやシステム開発などの技術に関する話題を、取り上げたりしています。

Docker+CentOS8にWordPressをインストールする

はじめに

前の記事では、Docker + CentOS 8に、nginxのコンテナ、php-fpmのコンテナ、MySQL のコンテナを構築して、連携して動作させる方法をご紹介しました。

www.aruse.net

この記事では、この環境に若干手を入れて、WordPress をインストールする方法をご紹介します。

内容が前の記事と重複するので説明を省いているところがありますので、不明な点は前の記事をご参照ください。

なお、インストールは基本的にコマンド実行で行い、ファイルを開いての編集はしない方向にします。

動作環境

Docker + CentOS 8 で構築するコンテナは以下の3つになります。

  • Web (nginx)
  • App (PHP,php-fpm)
  • DB (MySQL)

WordPress は DB コンテナにデータベースを作成し、Web に WordPress をインストールします。

また、永続化のために、Web コンテナと App コンテナで共通で使用できるボリュームを、DB コンテナのためのボリュームをそれぞれ作成します。

ディレクトリ構成

Docker のコンテナを作成するローカル環境のディレクトリ構成は以下のようになります。

wordpress
├── db
│   └── Dockerfile
│   └── my.cnf
├── docker-compose.yml
├── php
│   ├── Dockerfile
│   └── www.conf
├── share
│   ├── mysql_data       # MySQL のデータを永続化するディレクトリ
│   └── src              # web と php で共有する永続化ディレクトリ
└── web
    ├── Dockerfile
    └── nginx.conf

Web コンテナの構築

Web コンテナでは、nginx のインストールを行い、設定ファイルも取り込みます。

Dockerfile およびコンテナに取り込む nginx.conf は以下のようになります。

Dockerfile

FROM centos:8
RUN dnf -y update
RUN dnf install -y nginx wget ed
COPY nginx.conf /etc/nginx/nginx.conf
ENTRYPOINT /usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf

nginx.conf

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream;

# Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; index index.html index.php

# Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { try_files $uri $uri/ /index.php$is_args$args; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } } }

App コンテナの構築

App コンテナには、PHP と php-fpm、WordPress に必要な PHP モジュールなどをインストールし、php-fpm の設定ファイルをコンテナに取り込みます。

Dockerfile およびコンテナに取り込む www.conf は以下のようになります。

Dockerfile

FROM centos:8
RUN dnf -y update
RUN dnf install -y php php-fpm php-mysqlnd php-mbstring
RUN mkdir -p /run/php-fpm
COPY www.conf /etc/php-fpm.d/www.conf
RUN chown nginx:nginx /var/lib/php/session

www.conf

[www]
user = nginx
group = nginx
listen = 9000
listen.acl_users = apache,nginx
;listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

DB コンテナの構築

DB コンテナには、MySQL をインストールします。

なお、CentOS 8 からは、標準リポジトリに MySQL が存在します。

Dockerfile は以下のようになります。

Dockerfile

FROM centos:8
RUN dnf -y update
# install server & client
RUN dnf install -y @mysql
COPY my.cnf /etc/my.cnf
EXPOSE 3306

my.cnf は以下の通りです。

my.cnf

[mysqld]
user=mysql
default-authentication-plugin=mysql_native_password
lower_case_table_names=0

Docker Composeの設定

docker-compose.yml の設定は以下のようになります。

コンテナの永続化やプロセスの起動などが設定されています。また、DB コンテナが privileged な権限で実行されます。これは、MySQL を起動するのに Systemd の仕組みが必要なためです。

docker-compose.yml

version: '3'
services:
  web:
    build:
      context: ./web/.
    ports:
      - "8080:80"
    links:
      - php
    volumes:
      - ./share/src:/usr/share/nginx/html
  php:
    build:
      context: ./php/.
    command: php-fpm -F
    links:
      - mysql
    volumes:
      - ./share/src:/usr/share/nginx/html
  mysql:
    build:
      context: ./db/.
    command: /usr/sbin/mysqld --user=mysql --initialize #初回起動時
    #command: /usr/sbin/mysqld --user=mysql #2回目以降起動時
    privileged: true
    volumes:
      - ./share/mysql_data:/var/lib/mysql

初回起動時は、以下を使用します。

    command: /usr/sbin/mysqld --user=mysql --initialize #初回起動時

2回目以降の起動時は、こちらのコメントアウトを外して、初回起動時をコメントアウトします。

    #command: /usr/sbin/mysqld --user=mysql #2回目以降起動時

コンテナの起動

コンテナを起動するには、docker-compose.yml のあるディレクトリで、下記のコマンドを実行します。

$ docker-compose up -d
Creating network "wordpress_default" with the default driver
Creating wordpress_mysql_1 ... done
Creating wordpress_php_1   ... done
Creating wordpress_web_1   ... done

正しく起動されたか確認します。

$ docker-compose ps
      Name                     Command               State           Ports


wordpress_mysql_1 /usr/sbin/mysqld --user=my ... Exit 0
wordpress_php_1 php-fpm -F Up
wordpress_web_1 /bin/sh -c /usr/sbin/nginx ... Up 0.0.0.0:8080->80/tcp

起動に失敗している場合は、State が Exit になります。

wordpress_mysql_1 が Exit となってますね。これは初期処理が終了してコンテナが終了したので問題ありません。

ここでコンテナのログで、MySQL の root アカウントのパスワードを確認します。eUj=lfhu1Nq>となっていますね。後で使うので控えておきます。

$ docker-compose logs
Attaching to wordpress_web_1, wordpress_php_1, wordpress_mysql_1
mysql_1  | 2020-08-09T07:37:23.241420Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.17) initializing of server in progress as process 1
mysql_1  | 2020-08-09T07:37:30.757619Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: eUj=lfhu1Nq>
mysql_1  | 2020-08-09T07:37:34.773475Z 0 [System] [MY-013170] [Server] /usr/sbin/mysqld (mysqld 8.0.17) initializing of server has completed

一度、コンテナをすべて終了します。

$ docker-compose down
Stopping wordpress_web_1 ... done
Stopping wordpress_php_1 ... done
Removing wordpress_web_1   ... done
Removing wordpress_php_1   ... done
Removing wordpress_mysql_1 ... done
Removing network wordpress_default

ここで、先ほどのdocker-compose.ymlの2回目のコメントアウトを変更します。

    #command: /usr/sbin/mysqld --user=mysql --initialize #初回起動時
    command: /usr/sbin/mysqld --user=mysql #2回目以降起動時

コンテナを再度起動します。

$ docker-compose up -d
Creating network "wordpress_default" with the default driver
Creating wordpress_mysql_1 ... done
Creating wordpress_php_1   ... done
Creating wordpress_web_1   ... done

コンテナが起動したか確認します。

$ docker-compose ps
      Name                     Command               State          Ports


wordpress_mysql_1 /usr/sbin/mysqld --user=mysql Up 3306/tcp
wordpress_php_1 php-fpm -F Up
wordpress_web_1 /bin/sh -c /usr/sbin/nginx ... Up 0.0.0.0:8080->80/tcp

問題なく起動していますね。

データベースの設定

下記のコマンドで、DB コンテナにログインします。

$ docker exec -it wordpress_mysql_1 /bin/bash

下記のコマンドで、MySQL を初期化します。マンド実行時に、root アカウントのパスワードを聞かれるので、先ほど保存しておいたeUj=lfhu1Nq>を使用します。ここでは、root ユーザーのパスワードを「Mysql@1234」にしました。

# mysql_secure_installation

MySQL にログインして、mysql ユーザーを作成し権限を付与します。

# mysql -u root -p
mysql> CREATE USER 'mysql'@'localhost' IDENTIFIED BY 'Mysql@1234';
mysql> CREATE USER 'mysql'@'%' IDENTIFIED BY 'Mysql@1234';
mysql> GRANT ALL ON . TO 'mysql'@'localhost';
mysql> GRANT ALL ON . TO 'mysql'@'%';
mysql> FLUSH PRIVILEGES;
mysql> ALTER USER 'mysql'@'%' IDENTIFIED WITH mysql_native_password BY 'Mysql@1234';

WordPress 用のデータベースを作成します。文字エンコーディングは、サロゲートペア文字を使用したいので utf8mb4 にしています。

mysql> CREATE DATABASE wordpress CHARACTER SET utf8mb4;

DB コンテナからログアウトします。

mysql> quit;
# exit

WordPress のインストールと設定

Web コンテナにログインして、WordPress をインストールします。

$ docker exec -it wordpress_web_1 /bin/bash

WordPress の最新版をダウンロードして解凍します。

# wget http://ja.wordpress.org/latest-ja.tar.gz
# tar xvzf latest-ja.tar.gz

wordpress というディレクトリが作成されるので、そのディレクトリで作業を行います。

# cd wordpress

wp-config.php の設定を行います。

sed コマンドで、各項目を置換してファイルを更新しています。

# cp wp-config-sample.php wp-config.php
# sed -i -e 's/database_name_here/wordpress/' wp-config.php  #DB_NAME
# sed -i -e 's/username_here/mysql/' wp-config.php #DB_USER
# sed -i -e 's/password_here/Mysql@1234/' wp-config.php #DB_PASSWORD

wp-config.php には、ジェネレーターで生成したシークレットキーを設定する必要があります。通常はエディタで設定するのですが、コマンド実行で設定できる方法がありました。

# SALT=$(curl -L https://api.wordpress.org/secret-key/1.1/salt/)
# STRING='put your unique phrase here'
# printf '%s\n' "g/$STRING/d" a "$SALT" . w | ed -s wp-config.php

設定が終わったので、すべてのファイルの nginx の公開ディレクトリに移動して、Web コンテナをログアウトします。

# mv * /usr/share/nginx/html
# exit

次にブラウザで、http://localhost:8080/wp-admin/install.phpにアクセスします。

f:id:fnyablog:20191012071054p:plain:w480

ブログタイトル、ユーザ名、パスワード、メールアドレスを設定し、WordPress をインストールします。

インストールが正常終了したら、以下の画面が表示されます。

f:id:fnyablog:20191012071304p:plain:w480

ログイン画面に移動してログインしてみます。

f:id:fnyablog:20191012071445p:plain:w480

管理画面が無事に表示されました。

f:id:fnyablog:20191012071535p:plain:w480

http://localhost:8080/ にアクセスしてみます。

f:id:fnyablog:20191012071723p:plain:w480

ブログ画面も無事に表示されました。

念のため、永続化ができているか下記コマンドでコンテナを再起動しましたが、問題なく表示されました。

$ docker-compose down
Stopping wordpress_web_1   ... done
Stopping wordpress_php_1   ... done
Stopping wordpress_mysql_1 ... done
Removing wordpress_web_1   ... done
Removing wordpress_php_1   ... done
Removing wordpress_mysql_1 ... done
Removing network wordpress_default
$ docker-compose up -d
Creating network "wordpress_default" with the default driver
Creating wordpress_mysql_1 ... done
Creating wordpress_php_1   ... done
Creating wordpress_web_1   ... done

コンテナの終了

すべての作業が終わったら、忘れずにコンテナの終了を行います。

$ docker-compose down
Stopping wordpress_web_1   ... done
Stopping wordpress_php_1   ... done
Stopping wordpress_mysql_1 ... done
Removing wordpress_web_1   ... done
Removing wordpress_php_1   ... done
Removing wordpress_mysql_1 ... done
Removing network wordpress_default

おわりに

Docker + CentOS 8 に WordPress をインストールする方法をご紹介しました。

コンテナの構築には苦労しましたが、WordPress の構築は比較的簡単なようですね。

Docker の練習教材としてよいと思いました。