Docker PHPの各種バージョンの違いについて調べてみる

adventar.org

Day-3です。

カレンダーを見ると、「docker phpの各種バージョンの違いについて調べてみる」という事でネタが設定されていました。
これに従ってまいりましょう。
はて・・・

PHPの公式Dockerイメージ

https://hub.docker.com/_/php/
これのことです。なのだけども、「長すぎて全文じゃないよ」って書いてあるので、READMEを見ましょう

github.com

こちらをいろいろと覗いてみようかな、というのが本日のエントリーです。

  1. stretch/cli
    • 7.3.0RC6-cli-stretch, 7.3-rc-cli-stretch, rc-cli-stretch, 7.3.0RC6-stretch, 7.3-rc-stretch, rc-stretch, 7.3.0RC6-cli, 7.3-rc-cli, rc-cli, 7.3.0RC6, 7.3-rc, rc (7.3-rc/stretch/cli/Dockerfile)
  2. stretch/apache
    • 7.3.0RC6-apache-stretch, 7.3-rc-apache-stretch, rc-apache-stretch, 7.3.0RC6-apache, 7.3-rc-apache, rc-apache (7.3-rc/stretch/apache/Dockerfile)
  3. stretch/fpm
    • 7.3.0RC6-fpm-stretch, 7.3-rc-fpm-stretch, rc-fpm-stretch, 7.3.0RC6-fpm, 7.3-rc-fpm, rc-fpm (7.3-rc/stretch/fpm/Dockerfile)
  4. stretch/zts
    • 7.3.0RC6-zts-stretch, 7.3-rc-zts-stretch, rc-zts-stretch, 7.3.0RC6-zts, 7.3-rc-zts, rc-zts (7.3-rc/stretch/zts/Dockerfile)
  5. alpine3.8/cli
    • 7.3.0RC6-cli-alpine3.8, 7.3-rc-cli-alpine3.8, rc-cli-alpine3.8, 7.3.0RC6-alpine3.8, 7.3-rc-alpine3.8, rc-alpine3.8, 7.3.0RC6-cli-alpine, 7.3-rc-cli-alpine, rc-cli-alpine, 7.3.0RC6-alpine, 7.3-rc-alpine, rc-alpine (7.3-rc/alpine3.8/cli/Dockerfile)
  6. alpine3.8/fpm
    • 7.3.0RC6-fpm-alpine3.8, 7.3-rc-fpm-alpine3.8, rc-fpm-alpine3.8, 7.3.0RC6-fpm-alpine, 7.3-rc-fpm-alpine, rc-fpm-alpine (7.3-rc/alpine3.8/fpm/Dockerfile)
  7. alpine3.8/zts
    • 7.3.0RC6-zts-alpine3.8, 7.3-rc-zts-alpine3.8, rc-zts-alpine3.8, 7.3.0RC6-zts-alpine, 7.3-rc-zts-alpine, rc-zts-alpine (7.3-rc/alpine3.8/zts/Dockerfile)

6種類。
「stretch or alpine」と「clit or apache or fpm or zts」の組み合わせですね。
ただし、alpine/apacheだけない模様*1

OS別

stretch

debian:stretch-slimをベースにしています。 https://hub.docker.com/_/debian/

stretchて?という方は gihyo.jp

alpine

alpine:3.8をベースにしています https://hub.docker.com/_/alpine/

alpine触ったことねぇ・・・というときには

yoshinorin.net

構成別

apache

これはDebianの方にしかない。

php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

fpm

debian php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

alpine php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

cli

無印の php:7.3-rc もCLIとイメージを共同しているので、1番の素となるイメージがこれ!という感じかな・・・

debian php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

alpine php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

zts

ztsって何?は

qiita.com

debian php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

alpine

php/Dockerfile at ee78d7883237754eb68ffb281f5835f851797e05 · docker-library/php · GitHub

どんなPHPですか?

alpine-fpmを見ると、ビルド時にこんな感じのオプションが渡されている

 && ./configure \
        --build="$gnuArch" \
        --with-config-file-path="$PHP_INI_DIR" \
        --with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
        \
# make sure invalid --configure-flags are fatal errors intead of just warnings
        --enable-option-checking=fatal \
        \
# https://github.com/docker-library/php/issues/439
        --with-mhash \
        \
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
        --enable-ftp \
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
        --enable-mbstring \
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
        --enable-mysqlnd \
# https://wiki.php.net/rfc/argon2_password_hash (7.2+)
        --with-password-argon2 \
# https://wiki.php.net/rfc/libsodium
        --with-sodium=shared \
        \
        --with-curl \
        --with-libedit \
        --with-openssl \
        --with-zlib \

この辺りのことが公式のdocに書いてあるわけで。

README§Image-Variantsのとこ。

php:-cli

「his variant contains the PHP CLI tool with default mods」であり「Note that all variants of php contain the PHP CLI (/usr/local/bin/php).」であると。 「使い捨てコンテナ、もしくは他の何かを作るときのベースイメージとして使ってね〜」ということ

php:-apache

「mod_php/mpm_preforkを利用するApacheのやつ」で「Debianベース」と。

document rootの変え方だったり、その他のconfの変更についてもこの docで言及されておりました

php:-fpm

fomコミコミバージョン。

php:-alpine

「人気のあるAlpine Linux projectをベースにしたもの」で「可能な限りサイズの小さなdocker imageがほしい!」ということであれば、使うべきだ・・!と説明されており。

その他のこと

php.iniとかをいじりたい

$PHP_INI_DIR というい環境変数がセットされているから、それを使えるよ!とのこと。 source

ん〜、カレンダーにネタ登録したときはもう少し面白い掘り下げ方ができると思ったのだけど。
ただコピペしました!みたいなところで終わってしまった・・

*1:ちなみに訳あって私はalpine/apacheを欲しています

将太の寿司を読んだ

あどべんと関係ないカレンダーです。

僕も!!御多分に洩れず!そのビッグウェーブに・・乗った〜〜!! と言うことです。

11月の途中から、「将太の寿司」無料配信を読んでいました。全国編まで。 来る日も来る日も、暇な時、やる気が出ない時、どこかに移動する時、疲れたぜ〜!つってベッドに飛び込んだ後、今日は休みだからグダグダでいいや!といって寝間着のまま寝転がる時、 この月、私のオフタイムは将太の寿司と共にあった気がします。

漫画が無料?ふん!はしたないねぇ!!て気持ちがあって、最初は手を出さなかったんですけど、ツイッターに次々と流れてくるインパクトのあるコマやページは楽しく眺めてました。
で、あまりにも気力が湧いてこないタイミングがあり、何も考えたくなく、とにかく頭を使わせずかつ現実逃避をしたい何か情報をかっくやいたい・・という状態になり。そうだ、あの漫画・・とりあえず、家に帰って着替える間だけでいいや、助けてくれ・・・ それが最初の出会いでした。 序盤の方で、「おお、まじだ、なんでフルネームなんだよ藤原美智子www」ってなって凄く楽しかったです。

そして、少年漫画特有の「元気さ」「真っ直ぐさ」に、すぐに引き込まれました。はぁ〜、信じられないくらい嫌な奴が多いなぁ。。むかつく!て思いながら。でも将太は強い!いいぞいいぞ!やったぜ!!て。どこまでも応援したくなるじゃないですか。その一方で、ライバルもライバルで良いやつで凄いやつで頑張ってるやつで、あいつらも負けて欲しくないじゃないですか。あ、紺屋碧悟だけは負けちまえ。敵役の胸糞加減たるや錚々たるものなんですが、それをやっつけていくシズル感。心の中でガッツポーズしながら読んでいくわけです。

とんでもない量を読んでしまったなー、これの無料公開ってどういうビジネスになるんだろう?というのも気になるところなのですが、純粋に面白く読んで元気をいただきました。

ありがとうございました。

1人でAdvent Calendarをどうにかやっていきたい・・・ @day1

アウトプット足りないな〜と思わされる日々でして、

  1. そもそもの絶対量
  2. これだ!と言えるような、まとまった、あるいはやりきった感のあるパッケージ

のいずれ(か|も)が欲しいなーと。

で、世の中的には年の瀬・クリスマス前です。アドベントカレンダーか〜〜〜と。 2018年は、今までに比べれば少し外での登壇をしたりとか、社内ブログを書いたりとかして、少しずつ「アウトプット」を意識できたのかな?という気持ちがあります。 また、今の自分にとって「CakePHPやPHPっぽい話なら、そこそこまとまった量の話とかできるんじゃね?」って気持ちもあります。とりわけ、普段の業務をしていると、PHPや開発について「何かを考えさせられる」場面も少なくなく、考えるということは何かを生み出そうとしているということですから、本当であれば「普段から何かを生み出せているのでは?」と焦燥するわけです。とりわけ、コードレビューをしたりPRを書いていたりすると「あぁ、自分は、他人と交換するに足る知識や理解があったのだな」などと思います。

ということで、そんなジレジレした気持ちを発散する & 口だけで偉そうにして「実は何もできていない」自分の首を絞めるために、25本連続で書ききっちゃる・・・!と思ってしまったのが、今年の12月です。

どうなることやら・・・・・・

adventar.org

ということで、Day-1「まえがき」でした! 走り切ること優先で内容や分量は後回し・・・!

Pixela をSlackにつないで遊んでみた

小ネタ。
昨日が〜〜〜っとコーディングして、寝て、起きたのでブログです。

土曜日くらいから、たまたまSlackを題材にJSのお勉強!をしていて(それについては別途書く)、おもしれ〜少しわかってきたぞ〜〜となり、「他になにか作ろう〜〜」って気分でいたのですが、Twitterを眺めていたらあまりにもpixelaが盛り上がっていたので勢いで作ってみました。

blog.a-know.me

やったこと

Slack上で

  1. ユーザー登録ができて
  2. グラフの新規作成ができて
  3. グラフのインクリメントができる
  4. グラフ一覧も取得できる

必要最低限、って感じ。機能を絞ってインターフェイスをシンプルにした感じのv0.1。

ユーザー登録

  1. @bot pixela me とダイレクトメンションしたら起動
  2. tokenを自動生成する
  3. POST /v1/users を叩く
  4. SlackのユーザーID、Pixelaのusername,tokenを紐づけてDBに保存しておく
  5. 処理完了後、発話者のみ見える形でusername,tokenをSlack上に通知

この「SlackのユーザーIDと紐づけて格納して、実際のサービス(Pixela)のアカウント情報を隠蔽する」ってやり方が、何ともチャットbotぽいな〜とか思ったり。

イメージ

f:id:o0h:20181016124952p:plain

シーケンス

f:id:o0h:20181016125234p:plain

グラフ登録

  1. @bot pixela new とダイレクトメンションしたら起動
  2. 発話者のSlackユーザーIDをもとに、DBからPixela登録情報を引っ張ってくる
  3. conversationのセッションを開始
    • 対話的に「グラフID」「グラフ名」を入力する
    • グラフの詳細なオプション(色、単位、値の型)は現状だと省略。shibafu/cnt/intに固定
  4. POST /v1/users/<username>/graphsを叩く
  5. 処理完了後、登録された情報をリプライ

イメージ

f:id:o0h:20181016133859p:plain

シーケンス

f:id:o0h:20181016131700p:plain

インクリメント

  1. @bot pixela ${グラフID}++ とダイレクトメンションしたら起動
  2. 発話者のSlackユーザーIDをもとに、DBからPixela登録情報を引っ張ってくる
  3. PUT /v1/users/<username>/graphs/<graphID>/increment を叩く
  4. 処理完了後、操作対象となったグラフのURLをリプライ

イメージ

f:id:o0h:20181016132001p:plain

シーケンス

f:id:o0h:20181016131933p:plain

グラフ一覧

  1. @bot pixela list とダイレクトメンションしたら起動
  2. 発話者のSlackユーザーIDをもとに、DBからPixela登録情報を引っ張ってくる
  3. GET /v1/users/<username>/graphs を叩く
  4. 処理完了後、登録されているグラフの一覧をリプライ

イメージ

f:id:o0h:20181016132231p:plain

シーケンス

f:id:o0h:20181016132338p:plain

やっていないこと

概ね「対応してないエンドポイント」「対応していないパラメータ」も面白く使えるようにしたい・・というのがほとんど。 あとは、SVG to PNGを行うためのサーバーを自前で持つか何かをしたら、インクリメント後とか、サムネイル出せるようになるよな〜絶対にそのほうが楽しいよな〜という気持ち。。

あとは、グラフの登録のところ、ひっさびさにBotkitのconversationを使ってみたけどイマイチ・・・Interactive componentにしてフォームで入れたほうが便利っぽいな。

感想など

何個かSlackのbotを作っていて、「いまいち使う楽しさに欠ける」というのはインターフェイスの問題な事が非常に多いなと思っています。要するに「呼び出し方がわからない」「フォーマットが複雑」など。そこに関して、今回は 「私にPixelaを使わせろ!」という意味の me でアカウント登録、ほとんど"graph"がすべてのサービスにおいて「新しく始めるよ!」という意味の new で新規作成、 ++ でインクリメント・・・と、だいぶシュッとしたコマンドをデザインできたかな?という気持ち。

サービスを触っていて思ったのは、単機能&RESTFulなAPIデザイン素敵すぎる。ほとんどドキュメントは流し読みで、実際に動くところまで行けた!!というのが最高の体験でした・・・

正直、最初に見た時に「草が生えるよ!」というサービスって嬉しいか・・?とピンと来てなかったのだけど。数時間後に開いたTwitterで、たまたま別のツイートが目に入ってきて、「Slackに結びつけたら面白いかも?」と思ってから一気に書きました。
「とりあえず動かしてみたら面白いんじゃねwww」くらいのノリでさくさく〜っとマッシュアップできるサービスとかアイディアっていうのはストレス解消に良いですね・・・👼

今のとこ会社のSlackに置こうとしているだけだけど、もーちょい汎用化できたらOSS化するのはアリだよな〜とか。Storage周りどうしよーっていうとこだけ悩まし。
とりあえず、今やりたいのは「運動習慣をつけたい人たちが、運動をしたら報告するチャンネル」があるので「運動したら草を早そう」を盛り上げたいw

Botkit middleware を作ってみる作業メモ②

続き。

やること

  • [x] modern JavaScript なプロジェクトをセットアップしてみる
  • [x] Botkitアプリケーションに対して外から入れるような形のモジュールを作ってみる
    • Botkit middleware
  • [x] ローカルでのyarnを介したモジュール開発をしてみる
  • [ ] npmに登録してみる
  • [ ] サンプルアプリケーションを作成してみる
  • [ ] Deploy to Heroku で簡単に触って見られる、という感じにしてみる

第3章: npmへの登録

やっていきましょう。前回のステップでも大変お世話になった記事、続きを読んでいきます。

liginc.co.jp

「ソースはgit管理させつつ自動生成された最終成果物はgit管理させない、最終成果物はnpmに登録させつつソースは登録させない」か。そのためにbuildとprepublishが必要〜と。。

コマンドはrollup.jsの公式に載っている例をそのまま、で良い・・かな? f:id:o0h:20181014181825p:plain

ということで、

diff --git a/package.json b/package.json
index 02a630d..e7121b7 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
   "main": "dist/index.js",
   "scripts": {
     "watch": "rollup -cw",
+    "prepublish": "rollup -c --environment INCLUDE_DEPS,BUILD:production",
+    "build": "rollup -c --environment INCLUDE_DEPS,BUILD:production",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "repository": {

こんなんでいいのかな。

qiita.com docs.npmjs.com

Additionally, everything in node_modules is ignored, except for bundled dependencies. npm automatically handles this for you, so don't bother adding node_modules to .npmignore.

なのね。なるほど。

あとは、「タグを打ってgithubにpushしてnpmにpublishする」っぽい。

docs.npmjs.com

npm version patch
git tag
git push -f
git push origin v0.0.2
npm publish

やった〜〜〜!🎉🎉 f:id:o0h:20181014183529p:plain

READMEとか、あとでちゃんと整えよ・・・

publish打ったときに、

npm WARN prepublish-on-install As of npm@5, prepublish scripts are deprecated

と言われたのだけど。気になって調べてみたら、なんだか面倒くさいんですね・・・

qiita.com これもどっかしらで。

ひとまず、これで公開された!ということで、ローカルのパッケージを正常な状態にしてみる。

  • yarn unlink botkit-hashtag
  • yarn add botkit-hashta

ls打ってみたらちゃんと入ってるな〜〜!嬉しい。yarn.lockとかrollup.config.jsもnpmignoreしちゃっていいのかな?

$ ls -l node_modules/botkit-hashtag
total 192
-rw-r--r--  1 hkinjyo  staff   1070 10 14 18:49 LICENSE
-rw-r--r--  1 hkinjyo  staff     53 10 14 18:49 README.md
drwxr-xr-x  4 hkinjyo  staff    128 10 14 18:49 dist
-rw-r--r--  1 hkinjyo  staff   1323 10 14 18:49 package.json
-rw-r--r--  1 hkinjyo  staff    288 10 14 18:49 rollup.config.js
-rw-r--r--  1 hkinjyo  staff  81303 10 14 18:49 yarn.lock

第4章: サンプルアプリの作成 & deploy to heroku

ローカルでbotkitアプリを作りながら作業を進めてきていたので、それを少し整える。

  • yarn add botkit botkit-hashtag

あとは、dev系のツールは基本的にbotkit-hashtagと同じでいいかな〜という感じで。ただ、(楽をするために)勤め先のeslint-configに乗っかりたいので、依存するモジュールを足しておく

  • yarn add eslint-plugin-flowtype eslint-plugin-react

アプリケーションの内容は、 src/index.js に数行書いて終わりになりそ〜

そしてもう最後の山場?となる、Deploy to Heroku buttonである。

devcenter.heroku.com

今回でいうと、やりたいことは

  • 初回インストール時にENVの指定を案内できて
  • yarnで依存を解決できて
  • nodeアプリケーションを起動できて

くらいかなぁ。大したことがない! 👼
そういう観点で、 app.json の設置と一部 package.json の修正を加えて。

・・・で、ここで結構ハマったのだけど 基本的な事しかしないのであれば、package.jsonにだけ書いておけば十分に動くので、app.jsonのscriptsは必要なかった みたい。
基本的なこと => 要するに、

{
  "scripts": {
    "build": "rollup -c --environment INCLUDE_DEPS,BUILD:production",
    "start": "node dist/index.js",
    "postinstall": "yarn run build",
  }
}

あたり。これらを用いて、良しなにビルド&スタートしてくれた。app.json側にも同様に start などの動きを指定できるのだが、中途半端に使おうとしたためか、デプロイに失敗して暫くハマってしまった・・

formationの変更

ここまでで、ひとまずデプロイまではうまく行った・・・のだが、少し時間が経つと反応しなくなる。
ログを見る。

  • heroku logs -t --app $HEROKU_APP_NAME

Web process failed to bind to $PORT within 60 seconds of launch

と書いてある。
たどり着いたのがこの文書で、「あーたしかにworkerにしたほうが良いよね〜webで起動しているのにweb用のポートの待受ができていないよ!!」っていう理屈で落ちるのか、と。

[Slack]Botkitをherokuの無料プランで動かす方法

app.jsonの formation 、Procfile辺りが関係しそう。うまきゃって「workerだけ動かす」ができれば最高。

Platform API Reference | Heroku Dev Center

・・・なのだが、暫くハマってみて解決できなかった。。。*1

で、気持ち悪いのだけど「無理やりwebサーバー起動してしまえばいいのか」っていう発想の転換。会社で使っているbotkitベースのアプリケーションにはworkerの利用などの様子が見られず、なんで大丈夫なんだ?というところから得た解法。

index.jsを修正する。

diff --git a/src/index.js b/src/index.js
index c1f3d28..53014f3 100644
--- a/src/index.js
+++ b/src/index.js
@@ -3,6 +3,7 @@ const controller = botkit.slackbot({ debug: process.env.DEBUG })

 require('botkit-hashtag')(controller)

+controller.setupWebserver(process.env.PORT || 3000, (err, webserver) => {})
 controller
   .spawn({
     token: process.env.SLACK_TOKEN

いやー・・・👼

とりあえず動くようになりましたよ!

作業メモとしてはここらへんまで。

残タスクとしては

  • npmモジュールちゃんとする。いい感じにREADME入れる
    • botkitのmiddlewareでテスト書いてあるやつないかな〜参考になるのがあればちゃんとしたい
  • app側も使いやすくする。機能紹介+step-by-steoの導入を作る。qiita辺りかなー

*1:「webじゃないからか」という点に至るまでに、そもそも時間を要していて、そこからの「formationが組めないなぁ」の絶望たるや・・・何が悪いんだろうか。やり方は確実にあると思うのだけども。