Google Cloud Builder を使って PHP7.2 のアプリケーションを GAE に継続的デプロイする
Monday, September 24, 2018 06:52:00 PM
この記事は、PHPカンファレンス関西2018に参加してGAEに継続的デプロイする方法について発表してきましたの中で紹介しているGoogle Cloud Builderを利用してGAEのPHP SEへ自動デプロイするサンプルコードを最新に更新した解説記事です。
何が変わったのか?
PHPカンファレンス関西2018時点では以下のようになっていました。
- GAEのPHPは5.5
- Google Cloud Container Builder を利用
今日では以下のようになっています。
- GAEのPHPで7.2が利用可能に
- Cloud Container Builder は Cloud Build という名前に変更
gcloud コマンド利用上での変更
Dockerのバージョンがあがったことで gcloud
コマンドから docker
コマンドを実行するときに認証設定が必要になりました。
READMEにも反映していますが、以下のコマンドを実行しておく必要があります。
$ gcloud auth configure-docker
gcloud
コマンドをアップデートしてみましたが、「PUSH TO DEPLOY のトリガーをセットする」については、まだできませんでした。
projects.builds/create APIは実装されているようなので、CLIから実行できるようになるのを心待ちにしています。
composer イメージの更新
PHP7.2を利用できるようになったので、 composer/composer:php5
のDockerイメージを composer/composer:alpine
に変更しました。
composer/composer
でも良かったのですが、 alpine
ベースの方が軽量だし、いいですよね。
app.yaml の更新
基本的にここがメインなのですが、以下のような変更点があります。
- runtime を
php72
に変更 handlers
のapplication_readable
は常にtrue
にskip_files
でデプロイしないファイルの指定は.gcloudignore
ファイルへ移行する/
アクセスされたときのscript
指定はauto
に(ただしindex.php
かpublic/index.php
の場合のみで、他はパスを指定)
こういった変更は、Compatibility issues between PHP 5.5 and PHP 7.2にまとめられています。
※ skip_files
については書いていないので、実際にマイグレーションして確認は必要です(これは5.5から7.2の変更というよりは gcloud
コマンドのバージョンアップに伴うものだから書いていないのかもしれないです)。
デプロイしてみよう
あとは、用意したコマンドを順番に実行してデプロイ環境を整備してから、 git push
するだけで、PHP7.2のアプリケーションがデプロイできます。
githubのリポジトリが Cloud Source Repositories
にミラーされるところなどは変わっていませんでした。
さいごに
この内容は プレPHPカンファレンス北海道 で発表する予定だったのですが、地震の影響でイベントが中止となったため、このブログにまとめました。
どこかで機会があれば、GAEとPHP7.2について発表してみたいなと思います。
web-i2cエレメントをより使いやすくしました。
Monday, September 24, 2018 03:41:00 PM
先日のMaker Faire Tokyo 2018 に CHIRIMENコミュニティで参加しましたで web-i2c-element はどうなの?
に記述した改良ポイントを使ったchirimen-pianoをアップしました。
変更したポイント:
変更の概要は以下のとおりです。
no-web-i2c
スロットを指定すると、非対応メッセージを表示できるようになったWebI2cSensorElement
を使って、センサー毎の共通実装をなくし、より簡単にセンサーのカスタムエレメントが実装できるようになった- Polymer使ってなくても、タグだけを使ってセンサーの値が取得できるようなサンプルに変更した
では、それぞれの変更を詳しく見ていきましょう。
非対応メッセージの表示
chirimen-pianoのリポジトリにあるindex.htmlファイルを見てましょう。
<web-i2c>
<grove-touch slave-address="0x5a"></grove-touch>
<grove-gesture slave-address="0x73"></grove-gesture>
<div slot="no-web-i2c">
このデバイスはCHIRIMENではありませんが、ピアノ演奏はお楽しみいただけます。
</div>
</web-i2c>
web-i2c
タグの内側に no-web-i2c
というslot名のタグを記述することで、
もしCHIRIMEN以外のデバイス(例えばPCなど)から、このページを表示するとメッセージを表示することができるようになります。
試しに、PCからchirimen-pianoのデモページにアクセスしてみてください。
WebI2cSensorElementを利用したカスタムエレメントの記述
最初のバージョンでは、 PolymerElement
を使っていたため共通的な実装が多くなっていたのですが、
いくつかのセンサー実装をしてみて共通化できそうな箇所もわかってきたので、I2C用の親クラスを作ることにしました。
WebI2cSensorElement
を使ったセンサーのクラスとして、GROVEタッチとGROVEジェスチャーのカスタムエレメントを作りました。
例としてchirimen-pianoのリポジトリにあるgrove-touch.jsファイルを見てましょう。
class GroveTouch extends WebI2cSensorElement {
async init() {
this._autoRead = true;
await this._i2cSlave.write8(0x2b,0x01);
await this._i2cSlave.write8(0x2c,0x01);
await this._i2cSlave.write8(0x2d,0x01);
await this._i2cSlave.write8(0x2e,0x01);
await this._i2cSlave.write8(0x2f,0x01);
await this._i2cSlave.write8(0x30,0x01);
await this._i2cSlave.write8(0x31,0xff);
await this._i2cSlave.write8(0x32,0x02);
for(var i=0;i<12*2;i+=2){
// console.log(i);
var address = 0x41+i;
// console.log(address);
await this._i2cSlave.write8(address,0x0f);
await this._i2cSlave.write8(address+1,0x0a);
}
await this._i2cSlave.write8(0x5d,0x04);
await this._i2cSlave.write8(0x5e,0x0c);
}
async read() {
const value = await this._i2cSlave.read16(0x00);
// console.log(value);
var array = [];
for(var cnt = 0; cnt < 12; cnt ++){
array.push(((value & (1 << cnt)) != 0)?true:false);
}
if (!this.value || (JSON.stringify(array) != JSON.stringify(this.value))) {
this._setValue(array);
}
}
}
window.customElements.define('grove-touch', GroveTouch);
まず WebI2cSensorElement
を継承したクラスを定義します。
このクラスには2つのオーバライド可能なメソッドがあります。
- init
- read
どちらも async
メソッドにすることで I2Cスレーブデバイスからの応答を待ち合わせる(await
)ことができるようになっています。
WebI2cSensorElement
は、 init
呼び出し時にメンバー変数として _i2cSlave
が利用可能になっています。
これはWeb I2Cのスレーブオブジェクトで、どんなメソッドが使えるかはWeb I2C API Specificationの 4.6 Reading the value
や 4.8 Writing a value
を参照ください。
サンプルコードの slaveDevice
が _i2cSlave
と同じものになります。
init を実装する
init ではI2Cデバイスの初期化コードを記述します。 とくに戻り値は必要ありません。
もしセンサーが読み取り可能なら、 this._autoRead = true;
のように設定してください。
これを設定すると、インターバル間隔(デフォルトは100ミリ秒)ごとに read
メソッドを呼び出してくれます。
read を実装する
init で _autoRead
を true
に設定した場合、インターバル間隔ごとに呼び出されます。
センサーの値を読み取って、値が変わった場合は this._setValue(value)
を呼び出してください。
エレメントの value
プロパティに値が保持されると同時に、 value-changed
イベントが発行されます。
普通のHTMLからセンサーを取り扱う
ふたたびchirimen-pianoのリポジトリにあるindex.htmlファイルを見てましょう。
<script>
document.querySelector('grove-touch').addEventListener('value-changed', e => {
document.querySelector('chirimen-piano-app').touchChanged(e.detail.value);
});
document.querySelector('grove-gesture').addEventListener('value-changed', e => {
document.querySelector('chirimen-piano-app').gestureChanged(e.detail.value);
});
</script>
センサー値の変更を受け取るには、センサーエレメントに対して value-changed
イベントのリスナーを設定します。
値はイベントオブジェクトの detail.value
に入っていて、センサーによってセットされる値(型も含め)が違います。
たとえば grouve-touch
エレメントは、タッチセンサーの数分のBoolean配列がセットされ、 grove-gesture
エレメントは、発生したジェスチャー名がセットされます。
さいごに
このようにHTMLからセンサーの値をコントロールできたり、センサーのエレメントを簡単に実装できるようになりました。
今後は、それぞれのエレメントやベースクラスを npm install
で取得できるようにしたいと思っています。
また、以前作った WebGpioElement
も Polymer3
で書き換えていきたいなと思っています。
WebComponents と CHIRIMEN の融合は、私がそれぞれのコミュニティに参加して得られたもののアウトプットです。 もしこれらの活動に興味がありましたら、Polymer Japan CHIRIMEN Open Hardware Polymer.co-edo などの活動に参加ください。
Polymer.co-edo meetup #17 を開催しました
Monday, September 24, 2018 11:49:00 AM
今年8回目となる Polymer.co-edo ミートアップ を開催しました。
今回の議題は
Polymer3 を使って、カスタムエレメントを作ってみよう!
ということで、またまたcodelabsにある、Polymer1系のエレメント作成では定番の Build your first Polymer element ですが、 これをPolymer3用に移植しました!(ついでに日本語化もしたよ!)
codelabsのはじめかた
はじめての Polymer 3 エレメントの作り方を順番に読み進めるだけで大丈夫です。 イベント中でも特にはまりどころはありませんでした。 (スクショが微妙に違うという指摘を受けましたが、これはPolymer1のベースが間違っているという…)
Polymer1や2は触ったことがあるけど、3はまだ、という人にはオススメの教材になっていると思います。
GDG DevFest の codelab にも採用されました
GDG DevFest Tokyo 2018 CodelabsのWEBカテゴリにもリンクされました。 WEBは#20 Your First Progressive Web Appと、はじめての Polymer 3 エレメントの作り方でした。 WEB自体、トライしてくれる人は少なかったのですが、当日は何名かの方にPolymerを試してもらえて良かったです(Polymer Japanステッカーを差し上げました!)。
次回は
9月にも開催を予定していたのですが、日程が調整できず、10月に予定どおり開催できる見込みです。 Doorkeeperのコミュニティページに今年の予定も書いてあるので参考にしてください。
前回も書きましたが、そろそろ、edoエレメントの開発をしないとなー、なんて思っています…
Maker Faire Tokyo 2018 に CHIRIMENコミュニティで参加しました
Monday, August 13, 2018 04:17:00 PM
MFTokyo(昨年まではMFTと省略していましたが、今年からこのように変更となりました)のデモ準備として、 先日 CHIRIMEN Raspi setupという記事を書きましたが、これはその結果報告です。
デモ準備
実際にソースを書いて、動かしてみると 開封したばかりのGroveタッチセンサーが4つのうち1つだけ反応しません 。 ハブ側の裏にあるハンダ部分を触って通電させるとタッチ状態になるので、静電側が異常だということを認識し、 処理不良だから書い直せば大丈夫…と思い、前日の金曜日に秋葉原へ向かいしました。
実は8/3は半透明なブギーボード BB-11 の発売日で、翌日にMFTokyoへ持って行くなら量販店で買うしかない!と思いアキヨドにも行くつもりだったのです。 参考:13.8インチで半透明、ブギーボード新モデルが8月3日発売
何を作ったか
chirimen-piano という、ピアノアプリを作りました。
このアプリの特徴は以下のとおりです。
- Polymer3で作られていて、以下のCustomElementsの実装評価を兼ねていた
- web-i2c タグ
- grove-gesture タグ
- grove-touch タグ
- CHIRIMENでなくても動作するWebアプリである
- 4鍵(タッチセンサーの4つが対応)しかないが、左右に手を振ることでジェスチャーセンサーが反応し、音階が移動する。CHIRIMENでない場合は左右ボタンで移動
ちなみに昨年は Echigo という B2G OS ベースのボードで web-gpio エレメントを検証するために polymerchirimen というサンプルを作っていました。 これは人感センサーに反応すると、LEDが点灯するというものでした。
先日購入したものに追加して、以下の部品が必要になります。
- Grove - I2Cタッチセンサー
- Grove - I2C Hub
- GROVE - ジェスチャー
- Grove 4ピンコネクタ - ジャンパーピン変換ケーブル
- ラズパイに接続できるスピーカー, USBマウス(ちょっとした操作用), 電源アダプター
完成画像は以下のとおりです。
苦労したこと
CHIRIMENでなくても動作するWebアプリ
を目指して作り始めたら、Raspberry Pi版のpolyfillにいくつか問題があることがわかって、それを修正しながら進めたのでギリギリまで時間がかかりました。
こちら、まだchirimen-pianoにしか入っていませんが、近いうちに公式版へPRを送る予定です。
あとはセンサーの初期不良は、まぁあるものと思っていた方が良いですね。 最近あんまりハズレを引かなかったので忘れていました。
web-i2c-element はどうなの?
現時点はまだデモプログラム内での評価用ですが、今回思ったよりもうまく動作しそうなので、こちらもちゃんとエレメントとして分割したいです。 いくつか改善したいポイントがあります。
no-web-i2c 対応
まず CHIRIMEN 以外で動作させていたとき、 noscript
タグみたいにして書けるようにする予定です。
現在は web-i2c.js
にベタ打ちになっていますが
<div class="message">
このデバイスはCHIRIMENではありませんが、ピアノ演奏はお楽しみいただけます。
</div>
これを利用側から指定できるようにしたいと思います。
<web-i2c>
<div slot="no-web-i2c">
このデバイスはCHIRIMENではありませんが、ピアノ演奏はお楽しみいただけます。
</div>
</web-i2c>
WebI2cSensorElement 対応
センサーのタグは PolymerElement
を継承して作るようにしていますが、これを WebI2cSensorElement のように親クラスを作って、センサータグ実装を楽にしたいと思っています。
現在のgrove-touchエレメントのソースコード を、以下のように書けるようにしたいと思っています。
class GroveTouch extends WebI2cSensorElement {
async init(i2cSlave) {
await i2cSlave.write8(0x2b,0x01);
await i2cSlave.write8(0x2c,0x01);
await i2cSlave.write8(0x2d,0x01);
await i2cSlave.write8(0x2e,0x01);
await i2cSlave.write8(0x2f,0x01);
await i2cSlave.write8(0x30,0x01);
await i2cSlave.write8(0x31,0xff);
await i2cSlave.write8(0x32,0x02);
for(var i=0;i<12*2;i+=2){
var address = 0x41+i;
await i2cSlave.write8(address,0x0f);
await i2cSlave.write8(address+1,0x0a);
}
await i2cSlave.write8(0x5d,0x04);
await i2cSlave.write8(0x5e,0x0c);
}
read(i2cSlave) {
i2cSlave.read16(0x00).then((v)=>{
var array = [];
for(var cnt = 0;cnt < 12;cnt ++){
array.push(((v & (1 << cnt)) != 0)?true:false);
}
if (!this.value || (JSON.stringify(array) != JSON.stringify(this.value))) {
this.set('value', array);
}
})
}
defaultInterval() {
return 1000;
}
}
window.customElements.define('grove-touch', GroveTouch);
共通化のポイントは以下のような感じです。
- 値のプロパティを
value
で共通化 - エレメントのプロパティをWebI2cSensorElementで定義
- ポートのオープンや、web-i2cエレメントとやりとりしてポートを設定するところなどをWebI2cSensorElementで定義
- 値読み込みのインターバル制御をWebI2cSensorElementに移譲
2つのI2Cセンサータグを作ってみて、このぐらいは共通化しても大丈夫そうだし、便利そうだなと思っています。
on-change 対応
現時点はアプリもPolymerで書いているので、値の変更はデータバインディングでできているのですが、最終的にはタグから change
イベントを飛ばすようにする予定です。
つまり利用者はPolymerを使わなくても、以下のようなHTMLコードを追加するだけで利用可能になることを想定しています。
<html lang="en">
<head>
<script src="node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="node_modules/@chirimen/polyfill/polyfill.js"></script>
<script type="module" src="node_modules/@chirimen/web-i2c/web-i2c.js"></script>
<script type="module" src="node_modules/@chirimen/grove-touch/grove-touch.js"></script>
<script type="module" src="node_modules/@chirimen/grove-gesture/grove-gesture.js"></script>
</head>
<body>
何かしらのアプリ
<web-i2c>
<div slot="no-web-i2c">
このデバイスはCHIRIMENではありませんが、xxxxx。
</div>
<grove-touch slave-address="0x5a"></grove-touch>
<grove-gesture slave-address="0x73"></grove-gesture>
</web-i2c>
<script>
window.addEventListener('WebComponentsReady', e => {
document.querySelector('grove-touch').addEventListener('change', e => {
// 値が変わったときの処理
});
});
</script>
</body>
</html>
さいごに
WebComponentsを作るためのPolymerについては、 PolymerJapan コミュニティで活動しています。 毎月の集まりを Polymer.co-edoでも開催しているので、参加を待っています。
またCHIRIMENで、ブラウザからセンサーを動かしたいというような活動に興味があれば、コミュニティに参加ください。
どちらもユーザー主導で活動していますので、みなさまの参加をお待ちしております。
PHPカンファレンス関西2018に参加してGAEに継続的デプロイする方法について発表してきました
Friday, August 03, 2018 03:41:00 PM
2018/7/14 に行われたPHPカンファレンス関西2018に参加してきました。
今年も参加
昨年と同じくGRAND FRONT OSAKAで開催されました。
夜はスピーカーとスタッフの前夜祭から、コミュニティ前夜祭と合流しての2次会へと流れ、タクシーでホテルに戻りました。その後、3次会、4次会があったとかないとか…(これ毎年のコピペですwww)
PHPカンファレンス関西2018
PHPカンファレンス関西は3トラック+スポンサーブースです。朝一番の講演に参加者が多いのも特徴ですね。 今年はあまりセッションは聞かずに参加者と話したり、アンカンファレンスでPHPの非同期処理について話を聞いていたりしました。
私の発表はGAEへの継続的デプロイだったのですが、なんとタイムテーブルを見ると、私の前に
- Amazonの中の人が
PHPアプリケーションのコンテナ化入門
というタイトルで CI/CD の話をするらしい - Herokuの中の人が
HerokuでPHPアプリ開発速度を倍にする
というタイトルで 継続的デリバリー機能 の話をするらしい
ということでネタ丸かぶり?とか、私だけ中の人じゃないよ!とか心配になったので、この2つのセッションはしっかり前の席で聞きました。
GAEにPHPアプリを継続的デプロイする方法について発表しました
昨年に引き続きPHPネタですが、主にはDockerとGoogle Cloud Container Builderの話でした。
GAEを使っていて当然コードがPUSHされたらデプロイしたくなるのですが、何が良いのかよくわからない時期があって、調べて試した結果を発表するに至りました。 調べた過程で、まぁどんなツールを使っていても gcloud コマンドさえ動けば、あとはGAEと接続するための認証情報をそのCI/CDツールに最適な方法で管理するだけで、どんなものでも良いということがわかりました。 ただ、Cloud Container Builder使うとプライベートな空間を使えるわりには結構安いし、良いのではないかと思ったわけです。
デプロイのデモもギリギリ間に合って、ほっとしました。リポジトリの README に詳しい説明が書いてあるので、そちらを見ながらコードを動かしてみてください。
今回の発表をするのに30分でできる(当社比) Google Cloud Container Builderを利用した AppEngine SE環境への自動デプロイという記事が大変参考になったのですが、 GCPのコンソール(画面)から操作するのは、環境の再現性がなくて嫌だなーと思ったので、 gcloud コマンドを駆使して自動構築できるようにしました。 これは今回、かなり頑張ったところです。そしてデモ環境を何度も壊して作り直すことができたので、リハーサルも捗りました。
大阪を堪能
最終日は恒例の ねぎ焼き やまもと
へ。
今年はPHPerを4人(昨年は3人)引き連れ、梅田エスト店にやってきました。
そのあと有志で明石焼き/たこ焼きを食べに行って、聖地タイガースショップで買い物をして帰京しました。
さいごに
また来年も参加/発表したいので、1年の努力を惜しまずに…
Recent Articles
- GAE gen1 で動いている PHP5.5 で作った個人開発サービスを gen2 PHP8.2 へ移行した1年記 〜 その 2 2024/03/20
- GAE gen1 で動いている PHP5.5 で作った個人開発サービスを gen2 PHP8.2 へ移行した1年記 〜 その 1 2024/03/20
- マルチプルレポをモノレポへコミットログを残しながら移行する 2023/09/27
- tsyringe を TypeScript 5 で使う方法 2023/05/02
- LocalStack を使って aws-sdk の Integration Test を実行する 2023/04/19
- AWS SDK v3 のモジュールと利用方法 2023/04/18
- ts-jest が esbuild/swc をトランスフォーマーに使って高速化していた 2023/04/13
- aws-sdk v3 を使うライブラリを作ったときは、なるべく peerDependencies に設定しよう 2023/04/11
- aws-sdk v2 が 2023 年中にメンテナンスモードになる 2023/04/06
- Node.js v18 / aws-sdk v3 の Lambda アプリが突然動かなくなる 2023/04/05