知ることはたのしい

"車輪の再発明"は時間がもったいないと思うから"車輪の設計図"を置いて学習の効率化に役立ちたい。そしてもっと素晴らしいものを開発してくれないかな。

DockerでWordpress環境構築が簡単...じゃなかった

私が所属している研究室では自前のサーバでHPを運営しているのですが、サーバが古くなってきたため新環境への移行を行うことになりました。そこで今回は簡単に環境構築ができるとの噂のDockerでWordpress環境の立ち上げを試みました。同じことを考えている人は多数いて、参考になる記事やDockerイメージが多々ありますが、SSL認証を行うフェーズで苦戦しましたため後学のために記しておきます。



構築する環境

Docker・Docker Composeについて

このページを見ている方はDockerの導入は済んでいてその後の工程で躓いているのだと思います。そういった方はこの章は飛ばしていただいて構いません。

Dockerとは

Dockerとは仮想環境の一つです。このように言われると、VirtualboxVMware(以下仮想マシン)と同じではないかと感じるかもしれませんが、構成に明確な違いがあります。
仮想マシンは、私達が普段扱っている物理的なマシン(今回構築する環境ではCentOS)上に仮想的に新たなマシンを構築する手法で、いわばサーバ上でサーバを動かすエミュレータのようなものです。
Dockerはコンテナと呼ばれ、仮想マシンがOSも各自で持つのに対して、物理的なマシンが持つOSを共有しているのが大きな特徴になります。これによりリソースを共有することができるので仮想マシンに比べ少ないリソースで仮想環境構築が行えるという利点があります。
詳細は以下のリンクが参考になると思うのでより詳しく知りたい方はこちらをお読みください。

udemy.benesse.co.jp

また、どんなコンテナがあるのかということに関しては以下のDocker hubというページにまとまっていますのでご覧ください。データベースや各プログラミング言語の環境、各種OSなど本当に様々なものが用意されていることがわかります。

hub.docker.com

Docker Composeとは

Docker Composeとは、複数コンテナの運用を簡単に行うためのツールです。docker-compose.ymlというファイルにコンテナの情報(Dockerfileやイメージ、使用するポート、ネットワークなど)を記述することでwebページといった複数のコンテナで1つのアプリケーションを構築していたり、依存性のあるコンテナを用いたりする際に一元管理することができ非常に便利なものとなっています。
今回はDocker Composeを使っていきますが、導入や使い方に関しては下記のページなどをご参考ください。

knowledge.sakura.ad.jp

SSL認証+Wordpressの立ち上げ

Wordpressだけであれば非常に簡単です。しかし、Google検索から除外されてしまわないようにするためにはSSLサーバ証明書を発行してもらう必要があります。発行のための認証局は基本的にどこでも問題ありません。ただ、無料で発行する場合にはLet's Encryptから発行してもらうことが一般的のようです。本環境でも同様にLet's Encryptでのサーバ証明書で認証を行います。
SSL認証を行うためには自力でスクリプト等を用意しなければならないかというとそのようなことはなく、SSL認証を行うために作られたDockerイメージ、https-portalがあります。今回はこちらを利用していきたいと思います。

はじめの環境

当初の環境は上記のものとは異なっていて、物理マシン上にVirtualboxにて別IPを割り振ったCentOS仮想マシンにDockerでweb環境を構築する予定でした。この環境で自己証明書を用いたnginx+wordpressは用意できました。この環境をもとに開発を進めていきたかったのですが、SSL認証を行う過程でWordpressがうまく開けなくなってしまったので物理マシン上に直にDockerを置く構成となりました。

ソースコードと解説

それでは早速Docker Composeを用いたWordpress環境構築を行っていきたいと思います。使用したdocker-compose.ymlがこちらになります。



   db:
     image: mysql:5.7
     restart: always
     ports:
       - "3306:3306"
     volumes:
       # MySQL data       
       - ./data:/var/lib/mysql
     environment:
       MYSQL_ROOT_PASSWORD: root_password
       MYSQL_DATABASE: dbname
       MYSQL_USER: user
       MYSQL_PASSWORD: password

mysqlの設定です。複数バージョンのDockerイメージをインストールしていると正常動作しない恐れがあります。ここではバージョン5.7を入れていますが、このコードを実行することでコンテナが正常起動しなくなった場合は不要な別バージョンのイメージを削除してください。
削除を行う場合、まず$docker imagesでイメージの一覧を確認しましょう。イメージ名を確認できたら$docker rmi "イメージ名"で対象イメージを削除します。
環境変数(environment)のパラメータ(root_password, dbname,...)は各自の設定を記入してください。これは他のコンテナについても同様になります。

   phpmyadmin:
     image: phpmyadmin/phpmyadmin
#     environment:
#       - PMA_ARBITARY=1
#       - PMA_HOST=host
#       - PMA_USER=user
#       - PMA_PASSWORD=password
     depends_on:
       - db
     ports:
       - 8080:80
     restart: always
     volumes:
       - ./phpmyadmin/sessions:/sessions

phpmyadminのデータベースアクセス用の環境変数コメントアウトしています。私の環境では初めはコメントアウトしていませんでしたが、その際エラーコード200が発生したり、データベースのインポートを行おうとした際に匿名ユーザでログインされている様子で失敗したりしました。そこで、アクセス時に自分でログインを行えるようにコメントアウトすることで無事解決しました。

   php:
     image: wordpress:5-fpm
     depends_on:
       - db
     restart: always
     volumes:
       - ./php-uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
       - ./wordpress:/var/www/html
     environment:
       WORDPRESS_DB_HOST: host
       WORDPRESS_DB_USER: user
       WORDPRESS_DB_PASSWORD: password

wordpress+phpの設定です。php-uploads.iniは以下のようなコードを書いておりサーバへのアップロード容量の増加を目的としています。
/var/www/htmlwordpressの設定ファイルやコンテンツが格納されているフォルダです。volumesに書き永続化することで設定ファイルの変更やバックアップデータからの復元を行いやすくしています。

# php-uploads.ini
file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600
   web:
     image: nginx
     depends_on:
       - php
     restart: always
     volumes:
       - ./nginx.conf:/etc/nginx/conf.d/default.conf
       - ./wordpress:/var/www/html
       - ./logs:/var/log/nginx

/var/log/nginxを永続化させることでnginxのエラーログやアクセスログを容易に閲覧することができます。発生した問題によってはこのエラーログを読むことで原因の解明につながることもあるようです。

   https-portal:
     image: steveltn/https-portal:1
     depends_on:
       - web
     ports:
       - 80:80
       - 443:443
     restart: always
     volumes:
       - ./ssl_certs:/var/lib/https-portal
     environment:
       DOMAINS: 'mydmain -> http://web:80/ #production'
       CLIENT_MAX_BODY_SIZE: 64M

https-portalはLet's Encryptからサーバ証明書の取得・自動更新を行ってくれる非常に便利なコンテナです。特にLet's Encryptでは証明書の取得後有効であるのは90日間だけですので自動更新が行えるというのは強力なポイントとなっています。
./ssl_certsに取得したサーバ証明書のデータを保持しておきます。
私がかなり悩んでいたのがDOMAINS: 'mydmain -> http://web:80/ #production'の部分で、矢印の左側も右側も何を書いたら良いのかわかりませんでした。結局、矢印の左側はSSL認証を行うサーバのドメイン名(このページだとlenia23.hateblo.jp)で、右側はwebサーバであるnginxのコンテナ名(web)の80番ポートでした(IPアドレスwordpressのコンテナ名などを書いていました)。

おわりに

悪戦苦闘しましたがこれでなんとか証明書付きのwebページを構築することができました。今回は旧サーバからの移行なのでデータをこの環境に移せば作業は完了となります。
移行方法についても簡単に説明しておくと、まずWordpressプラグインBackWPupからデータベースやコンテンツのバックアップを取得します。そして、永続化した./wordpressフォルダにコンテンツ等を上書きし、phpmyadminでデータベースのインポートを行えば終了となります。ドメイン名が変わった場合は、Search Replace DBを利用してURLの書き換えを行ってください。