はじめに

WordPressは世界中の多くのBlogや企業サイトで利用されてているContents Manager System (CMS) です。 ソフトウェアとしてみた場合に非常に容易に導入できる点などから非常によくハンズオンやサンプルで利用されることが多いです。 WordPressは、フロントエンドのWebサーバ、Wordpressを実行させるライブラリであるPHPをどうやって動かすか、データを格納するDB(MySQL)をどうするか、投稿データの管理をどうするかなど一通りのWebシステムの基本的な事を全て網羅しているので非常に勉強の題材としても魅力的なアプリケーションとなります。今回はそんなWordPressを利用してBluemixのことを学びたいと思います。

Bluemixにおける課題

WordPressを利用する上で大きな課題点としては

  1. 名前解決に類する課題(Bluemixでは常にFDQNが必要になります)
  2. ストレージに類する課題(PaaSの性質上データの永続化は検討の必要があります)
  3. デプロイの課題 (デプロイを行った時点で、オンライン中の変更が消えてしまう、2にも関連する課題)

となります。これらについて解決する方法を含みながら進めていきたいと思います。

用意

Bluemix上での構成

事前準備

  • Bluemixのアカウントを取得していること
  • ローカルのPC/Mac上にcfコマンドの導入が実施済みであること
  • エディタ(メモ帳やviで構いません)
  • gitコマンド、wget(またはcurl)コマンド (こちらは無くても実施可能です)

今回のハンズオンでは以下の内容を取り込みながらBluemix上にWordpressサイトを作るところまでを実施します。

  • Bluemix上のPHPランタイムではアプリケーションのPHPライブラリの管理は Composer が利用されます。したがってこの中でPlugin等を制御します。
  • DBサービスへのアクセス情報はwp-config.phpに記載されますのでVCAP環境変数を参照するようにすることで動的に変更が可能になります。
  • メディアデータの保管には、ObjectStorageへ保管するプラグインを利用します。これにより投稿データはDBとObjectStorageに保管されます。

今回構成する概要図は以下のようになります。

NewImage

ソースコードの用意

今回のハンズオンの元になるのは2番めにダウンロードしている「Wordpress on Bluemix」になります。こちらでは場合には WordPress 本体も含めて全てデプロイ時に各種ファイルをダウンロードして利用する方法になりますがカスタマイズがしづらい事もあるのでローカルで環境を用意して進めます。そのためダウンロードしたファイルの一部を利用するなどをしていますので各自実際に利用する際にはご注意下さい。

ローカルのワークディレクトリ以下で以下の作業を実施します。

WordPressのソースコードのダウンロード

のサイトよりダウンロードすることが出来ます。

wget https://ja.wordpress.org/wordpress-4.5.2-ja.zip
unzip wordpress-4.5.2-ja.zip
cd wordpress

WordPress on Bluemix の内容をダウンロードして上書きします

git clone https://hub.jazz.net/git/jstart/WordPress.on.Bluemix
mv WordPress.on.Bluemix/composer.json .
mv WordPress.on.Bluemix/manifest.yml .
mv WordPress.on.Bluemix/lib/.htaccess .
rm -rf WordPress.on.Bluemix

wp-bluemix-config のダウンロード

git clone https://github.com/ibmjstart/wp-bluemix-config.git
mv wp-bluemix-config/wp-config.php .
mv wp-bluemix-config/mu-plugins wp-content/
rm -rf wp-bluemix-config

これで準備は出来ました。

設定

manifest.ymlの設定

BluemixのACEコンソール上においてランタイムを起動してもよいのですが実際には manifest.yaml に従い cf コマンドで設定されるため以下の手順でデプロイまでが出来ます。先ほどダウンロードした WordPress on Bluemix の中に manifest.yml が含まれています。

みてもらうと分かるのですがポイントは Buildpackとして指定されているのが カスタムビルドパックになります。これは後ほど利用するObjectStorage用のプラグインで利用しているライブラリがPHP7を前提に作られているためです。今回指定するのはCloudFoundryで用意しているPHPビルドパックとなります。

---
declared-services:
  myObjectStorage:
    label: Object-Storage
    plan: Free
  myClearDB:
    label: cleardb
    plan: spark

applications:
- name: WordPressForBluemix
  memory: 256M #The maximum memory to allocate to each application instance
  instances: 1 #The number of instances of the application to start
  buildpack: https://github.com/cloudfoundry/php-buildpack#v4.3.7
  services:
  - myObjectStorage
  - myClearDB

この内容を以下のように変更します。

  1. アプリケーション名は適切(なんでも良いですが mybluemix.net ドメインの中で一意になるひつようがあるためユニークなものにしておきます)
applications:
- name: samplewordpress01
  memory: 256M 
  instances: 1 
  buildpack: https://github.com/cloudfoundry/php-buildpack#v4.3.7
  services:
  - myWpObjectStorage
  - myWplearDB

利用するサービスをオーダ

Bluemixではこのmanifest.ymlで指定されている declared-services ではサービス登録が出来ないので以下のようにコマンドで登録を行います。

$ cf marketplace -s cleardb
Getting service plan information for service cleardb as hideaki_tokida@niandc.co.jp...
OK

service plan   description                                                                     free or paid
spark          Great for getting started and developing your apps                              free
boost          Best for light production or staging your applications                          paid
shock          Designed for apps where you need real MySQL reliability, power and throughput   paid
amp            For apps with moderate data requirements                                        paid

$ cf create-service Object-Storage Free "myWpObjectStorage"
$ cf marketplace -s Object-Storage
Getting service plan information for service Object-Storage as hideaki_tokida@niandc.co.jp...
OK

service plan   description                                                                                                                                                                                                                   free or paid
Free           Provider side encryption not available. It is the responsibility of the client application to encrypt data prior to upload.                                                                                                   free
standard       Instances can use Swift storage across all available regions, regardless of provision location. Provider side encryption not available. It is the responsibility of the client application to encrypt data prior to upload.   paid

cf create-service cleardb spark "myWpClearDB"

ここで作成する”名前”は、manifest.yml で指定する名前にします。

composer.jsonの設定

次に編集するのはこの WordPress on Bluemix のキモになっている composer.json の設定です。

このComposerの仕組みはPHPのライブラリを管理するために利用されます。今回はBluemixで利用していますが、Composer自体は一般的なシステムで用いられているメジャーな方式になります。今回はWordpressに必要なプラグインやテーマをを導入するために利用します。
Bluemixでは、Wordpressの実行中に管理コンソールからアップデートやInstallしたプラグインやテーマを永続的に保管することが出来ません。そのため今回は Composerを利用してプラグインを管理できるようにします。

{
    "repositories": [
        {
          "type": "vcs",
          "url": "https://github.com/ibmjstart/wp-bluemix-objectstorage.git"
        },
        {
          "type": "vcs",
          "url": "https://github.com/ibmjstart/wp-bluemix-config.git"
        },
        {
          "type": "composer",
          "url": "https://wpackagist.org"
        },
        {
          "type": "vcs",
          "url": "https://github.com/php-opencloud/openstack.git"
        }
    ],

    "scripts": {
        "pre-install-cmd" : [
            "curl https://api.github.com/rate_limit"
        ],
        "post-install-cmd" : [
            "mv vendor/ibmjstart/wp-bluemix-config/mu-plugins htdocs/wp-content/mu-plugins",
            "mv vendor/ibmjstart/wp-bluemix-config/.user.ini htdocs",
            "mv vendor/ibmjstart/wp-bluemix-config/wp-config.php htdocs",
            "mv vendor htdocs/vendor",
            "mv lib/.htaccess htdocs"
        ]

    },

    "require": {
        "ext-gd"                                      : "*",
        "johnpbloch/wordpress"                        : "*",
        "ibmjstart/wp-bluemix-objectstorage"          : "~2.1.1",
        "ibmjstart/wp-bluemix-config"                 : "dev-master",
        "wpackagist-plugin/stops-core-theme-and-plugin-updates": "*",
        "wpackagist-plugin/sendgrid-email-delivery-simplified": "*",
        "wpackagist-plugin/wp-super-cache"            : "*",
        "wpackagist-theme/twentyfourteen"             : "*",
        "wpackagist-theme/twentyfifteen"             : "*",
        "wpackagist-theme/twentysixteen"               : "*"
    },

    "extra": {
      "wordpress-install-dir": "htdocs",
      "installer-paths": {
        "htdocs/wp-content/plugins/{$name}/" : ["type:wordpress-plugin"],
        "htdocs/wp-content/themes/{$name}/"  : ["type:wordpress-theme"]
      }
    },
    "minimum-stability" : "dev",
    "prefer-stable": true
}

このファイルを以下のように変更します。

  1. wordpress本体のダウンロードを除外
  2. wordpress-on-bluemixについてはローカルにダウンロードしているため除外
  3. 上記に付随する関連部分としてscriptsのセクションから除外
  4. その他 wordpressのプラグイン(require)の修正
{
   "repositories":[
        {
          "type": "vcs",
          "url": "https://github.com/ibmjstart/wp-bluemix-objectstorage.git"
        },
        {
          "type": "vcs",
                  "url": "https://github.com/tokida/wp-bluemix-config.git"
        },
        {
          "type": "composer",
          "url": "https://wpackagist.org"
        },
        {
          "type": "vcs",
          "url": "https://github.com/php-opencloud/openstack.git"
        }
    ],
    "scripts": {
        "post-install-cmd" : [
            "mv vendor htdocs/vendor"
        ]
    },
   "require": {
            "ibmjstart/wp-bluemix-objectstorage"          : "dev-master",
            "wpackagist-plugin/stops-core-theme-and-plugin-updates": "*",
            "wpackagist-plugin/akismet": "*",
            "wpackagist-theme/evolve": "*"
        },
        "extra": {
      "installer-paths": {
        "htdocs/wp-content/plugins/{$name}/" : ["type:wordpress-plugin"],
        "htdocs/wp-content/themes/{$name}/"  : ["type:wordpress-theme"]
      }
    },
        "minimum-stability" : "dev",
        "prefer-stable": true

}

wp-config.php の設定

wordpressを導入する際にはこの設定ファイルをまず修正することになります。その際DBサーバの設定を記載するのが常ですが今回最初の手順でダウンロードしている wp-bluemix-config の中で既に設定されています。 Bluemixでは、ランタイムにバインドされたサービス(今回はMySQLサービスであるCleardb)の認証情報を VCAP環境変数より取得することが出来ます。従って wp-config.php の中ではそれを指定することで対応することが可能になります。

$vcap = getenv("VCAP_SERVICES");
$data = json_decode($vcap, true);
$creds = $data['cleardb'][0]['credentials'];
define('DB_NAME', $creds['name']);

/** MySQL database username */
define('DB_USER', $creds['username']);

以下のようにwp-config.phpを変更します。

上記のように記載されていますので環境が変わっても同じコードで利用できるのはBluemixの良いところです。
Wordperssの良くないところは、サイトのURLを含んだ文章がDBに格納されてしまし容易にドメイン名を変更できない点に有ります、Bluemixでもそれは同様です。
Wordpressではサイト名自体は wp-config.php に含めることが出来ますので以下の2行を wp-config.php に追加しておきます。

/** for change hostname  **/
define('WP_HOME', 'http://'.$_SERVER['HTTP_HOST']);
define('WP_SITEURL', 'http://'.$_SERVER['HTTP_HOST']);

導入(デプロイ)

デプロイ

ここまで出来たらあとはデプロイするのみです。

cf push

を行います。

設定

デプロイが完了できたらサイトにアクセスしてみます。初期設定が終わっていませんので以下の様な画面が表示されます。

NewImage

導入が完了し、admin ( /wp-admin ) にアクセスると設定メニューの下の方に以下のようにObjectStorageが表示されています。

NewImage

以下の様な設定を行うことが出来ます。

NewImage

実際にメディアから画像の投稿を実施すると以下のように objectStorageへのURLが生成されている事がわかります。

NewImage

色々試してみてください。

追加の課題

以下のことが出来るようになっています。

  1. 再度 cf push を実施してもオンライン中にアップした画像ファイルが正しく表示される。
  2. manifest.yml ファイルに必要なプラグインを追記すると起動時に導入されている
  3. ローカル側にある環境を、「ローカル側のphp環境」で実行することが出来る(※この際には wp-config.php のDBの設定は変更が必要です)
  4. メールの配信は、Wordpressのプラグインを利用して sendgridサービスから発信することが出来ます。

これでハンズオンは終了です。

まとめ

Bluemixの課題に対して

名前解決に類する課題(Bluemixでは常にFDQNが必要になります)

Bluexmixのアプリケーション名が変更になってもアクセス出来るようにするために wp-config.php の中に環境変数の設定を行いました。実際にサイト名が変わる場合にはDBの中にもFDQNが入っていますので修正が必要です(この辺りは普通にググると色々プラグイン等が出てきます)

ストレージに類する課題(PaaSの性質上データの永続化は検討の必要があります)

WordPressでは、RDBとしてMySQLを利用します。Bluemixでは、MySQLサービスとして「ClearDB」とCompose「MySQL」があります。今回は ClearDB を利用しました。それぞれ特徴があるので選択をしましょう。
またローカルのディスクに保管される「メディア」や「テーマ」などの情報の管理が必要になります。Runtime内に含まれる情報は、再デプロイ実行時には消えてしまうのでこの部分を外部に保存する必要があります。今回は投稿時に利用するメディアに関しては「ObjectStorage」へ保管してくれるプラグインを利用しました。

デプロイの課題 (デプロイを行った時点で、オンライン中の変更が消えてしまう、2にも関連する課題)

オンライン中の変更は2.同様の理由によりデプロイ「元」の方をどのようにするかを検討する必要があります。今回はComposerを利用してデプロ時にプラグインを導入する(または「最新」する)事が出来るようにしています。この辺りは実際の運用イメージとの兼合いで選択するのが良いでしょう。

全体

Bluemixの様なPaaS環境においては、従来の構成と違い「永続データ」について考えていく必要が有ることがわかりました。このようなプラットフォームの制約を鑑みてシステムを構成することが出来れば十分にPaaS環境の利点を活かしてシステムを構築できることが理解頂けたと思います。
またBluemixでは表面的には「Runtime(PHP)」という表現をしていますが実際には、Buildpackに含まれるランタイムのバージョンに気をつける必要があることや、Runtiemの中身としてどのようなWebフレームワークが利用されているかを知る事も必要です。今回PHPを活用しましたが例えばNodejsの場合にはExpressが利用されていたりとそれぞれのランタイムの特徴をしる事も重要です。

仮に実際にBluemix上でBluemixを管理する場合にはこれ以外にも冗長構成や監視方法などを検討していく必要があります。いわゆる従来出来ている事を制約の中で実施するかというクラウドデザインパターンに類する知見が必要になってきます。 Bluemixには多数のサービスが用意されていますのでそれらを上手く活用して行きましょう。