ぱいぱいにっき

Pythonが好きすぎるけれど、今からPerlを好きになりますにっき

WebSocketをいい感じに扱ってくれるミドルウェアkuiperbeltのDockerfileを作ってDockerHubに上げた

要約

  • WebSocketをいい感じに扱ってくれるミドルウェアkuiperbeltのDockerfileを作った
  • Docker対応のために幾つかの事柄をやった
    • オプションを環境変数で渡せるようにするとか
  • あとまあいろいろやった

経緯

  • YAPC::Okinawaで結構大々的に宣伝をした(つもり)なんだけれど、いろいろ残念なところを直しておきたいと思ったのでいろいろやっていた
  • README.md のインストール方法が腐っているとか
    • Goは基本go getでコマンドインストールできる。けれどkuiperbeltはdepで依存ライブラリのバージョン固定をしており、go getはそんなの無視して最新バージョン取ってきたりローカルにすでにあるバージョンを使おうとして、インターフェイスが変わるとコンパイルに失敗する
    • あと単体コマンドで動くやつはGoコンパイラは要らないので、release binaryを用いるのが吉。kuiperbeltは以前からこれを提供していた
  • ところでrelease binaryがあるツールはid:Songmuさん作のghgを用いると、OSやアーキテクチャを考慮してダウンロードしてくれるので便利ということが知られていますが、kuiperbeltはrelease binaryのパッケージングがghgに対応していなくて適用できてなかった
    • というのをYAPC::Okinawaのスライドを書いている時に気がついた
  • しかしパッケージングを変更すると会社の方で使われているアプリケーションで影響があるのでは?(chefレシピとか)と社内Slackで言ったら「それよりもDockerfileの変更がある」と言われて、たしかに今はDocker上で動かしているからそうか〜となった
  • というわけでパッケージング変更と公式Dockerfile/docker imageの配布をすすめることにした

やったこと

パッケージング変更

  • そういえばGoのツール作る時にビルドやらテストやらrelease binary上げるのとか毎回コピペやなって思った
    • コピペでやるよりは自分用テンプレがあるとええやろと思い、作った

github.com

  • 中身はdepとかクロスコンパイルツールgoxzGitHub releaseに生成物を上げるghrとかをインストールしたり、所定のディレクトリに生成物をはいたり、それをアップロードするMakefileの雛形みたいなやつ
  • これをkuiperbeltから使うようにした

github.com

Dockerfile作成

  • 課題として、Docker内で動作するkuiperbeltに対してオプションをどのように渡すかという問題がある
    • 現状、kuiperbeltは数多くのオプションをyml形式で設定ファイルを記述することで行っている
  • Docker containerで設定ファイルを必要とするアプリケーションは基本的にはボリュームマウントするか、イメージビルド時に含めてしまうか、はたまた起動時にS3からcurlスクリプトで引っ張ってくるとかそういうのが必要
    • 全部めんどくさい
    • 社内ではイメージビルド時に含めつつ、インスタンスによって変動しそうな要素は起動時に環境変数から設定ファイルに書き込むようにしている
  • あと、コンテナ起動時の引数で渡す方法と、環境変数で渡す方法がある
  • まあ環境変数でやるのが一番簡単
  • しかし、たくさんのオプションを環境変数で使えるようにするのめんどいなってなる
  • ところがkayac/go-configって言う便利なやつがあるっぽいのでそれを使うことにした。べんり
  • あとは最近入ったmulti stage buildなんか使ってscratchイメージベースなので結構軽い。4MBです。お試しあれ
$ docker pull mackee/kuiperbelt:latest
  • static buildしたGoバイナリってパフォーマンスにどれ位影響あるのだろうか。今度ベンチマークを取って試してみたい

サンプルアプリもdocker-composeで試せるようにする

  • 簡単なチャットアプリが_example以下に元々入っている
  • Perl/PSGI
  • PerlのPreforkサーバでも刺さらないWebSocketアプリケーションが書けるというのを示すためのもの
    • sinatraとかflaskでも作ろうかなとは思っているけれどまだやる気が出ない
  • ビルドするのに現代Perlの知識が必要だったので、これもDockerに押し込むことにした
  • 具体的にはdocker-composeでkuiperbeltとデータストアとして利用するRedisを立てつつ、ローカルのPerlアプリケーションが動作するコンテナもビルドする
    • 仕事で得た知識を使っていて、例えば依存が書かれたcpanfileだけをCOPYしておいてその上でcpmで依存入れた後に必要なapp.psgiとかindex.htmlをCOPYする戦法で行くと、依存の変更が無ければ全モジュールインストールし直しでビルド時間がなが~いにならない
    • 普段はこういう仕事を時々やってます
  • あと立ててみたら不審な動作をしていたので、チャットメッセージのブロードキャスト部分を大幅に直した
  • このコンテナも実は別タグでDockerHubから落とせます
$ docker pull mackee/kuiperbelt:webchat-example
  • 今はBootstrap + jQueryで貧相な感じの見た目だけれど、Vue.jsとUIツールキットライブラリ使ってもっとまともな感じにはしたいと思っております
  • 直している時に、そういえばXSSヤベーんじゃねと思ってネットでググって出てきたXSSロケーターなるものを入れてみたら案の定ポップアップして笑ったので、Perl側でHTML::Escape噛ました。あと、クライアントの生成したUUIDをそのまま使っているので、それを無視してPerl側でUUIDを生成するようにした。これでも大丈夫なんです
  • クライアント側にはリトライ機構とか入ってないし、アイドルタイムアウトの機能も使ってないので、そのへんも手を入れたいけれど、JSの知識がない。

その辺の試行錯誤はこちら

https://github.com/mackee/kuiperbelt/pull/48github.com

試したい場合は、

$ git clone https://github.com/mackee/kuiperbelt
$ cd kuiperbelt/_example
$ make up
$ make open

で終わりです。お試しあれ

DockerHubに上げる

  • 当初、travisのdeployにあるのかなと思ってたけれど、そんなことはなくて、DockerHubからGitHubの連携やるとwebhookか何かで変更検知して自動ビルドしてくれるっぽい。便利
    • タダ枠だからなのかしらないけれど、ビルドキュー入ってからイメージできるまでは結構時間がかかる
  • というわけで公式イメージです

https://hub.docker.com/r/mackee/kuiperbelt/hub.docker.com

README.md更新

  • ちょっとだけ気合を入れて書き換えた
  • ところで英語はかなりできないです。トラウマがあるレベル
  • 今回はGrammerlyGoogle翻訳を併用しつつ書いたけれど、まだまだ意味不明な文があると思う。つらい
  • どんな機能があるか分からんという声があったので、APIとCallbackのsummaryみたいなものを作ってみた

github.com

  • 少しは見栄えが良くなったのではないのでしょうか

お知らせ

  • kuiperbeltではユーザを募集しております
    • 内需要を満たすだけだと多様性がないもので。。。
  • 使って作ってみたとかあれば教えてください
    • どうぶつタワーバトルのコピーを習作として作りたいと去年末から思っておりますが、なかなか取り掛かれておりません
  • あと見栄えのするロゴね……