(金)永和システムマネジメント様と合同勉強会を開催しました@ucsmkyです。先日永和システムマネジメント(以下ESM)様と合同勉強会を開催しました。事のきっかけ突然なんだという話ですが、事のきっかけは昨年12月のRubyKaigiのDrinkupでのことです。ESMの伊藤さん(@koic)と話してた時、「最近永和さんいろんな会社さんと合同勉強会を開催されてますよねー」という話になってから、勢い余って私が「じゃあ今度一緒にやりましょうよ」と言った所伊藤さんも「よしやりましょう」、と。因みに1月はDRECOM様との予定があるので、その次に、ということで取り敢えず予定だけ頂きました。(因みにDRECOM様との開催はこちら)で、テーマについてですが、打ち合わせた結果、以下の内容で決まりました。ワールドパブ「クラウド×Agile」ワールドパブとはワールドパブというのはワールドカフェのアルコールあり形式のスタイルでファシリテーション手法の一種です。ワールドパブとは過去事例で言いますとクラスメソッド様とESM様の合同勉強会がその形式でした。各々のテーブルごとにテーマを決めて意見交換を行うというスタイルです。各テーブルごとにテーブルオーナーを決めておく必要があります。テーマは最終的に以下の内容で決まりました。強いチームリモートワーク各テーブルごとのディスカッション内容とまとめはESM様のサイトを参照していただければと思いますhttp://agile.esm.co.jp/news/2016-03-30-flect-esm-world-pub.html参加してからの気付き私はテーブルオーナーとして参加したので、他のテールブルの話題については実際に参加された方の意見を以下に抜粋します。参加された方の意見お酒と食べ物でリラックスしながらお話するのは、たのしいですね。初対面の方とも和やか雰囲気でお話できて、大変、楽しかったです。一方で、ほんとうの課題についてなかなか深掘りできない、という面もあったかもしれません。ひとりで悩んだり、考えこんだりしているよりは、みんなに話して意見をもらう、というのは改めて課題の整理ができて、非常に良い経験でした。リモートワークは今後より広がってゆくことが望ましいけど、業務量の制限やミーティングの調整などチームメンバーの文化が整えてゆくことが重要だなぁ強いチームになるには、メンバーがお互いに変な恐怖を抱かず意見がいえる環境が必要だなぁチームの状況と目的がまずはじめにあってそれからAWSやHerokuなどツールを選択することが重要だなぁなど、当たり前のことながら、課題をクリアするための本質的な点を再確認できたことが良かったです。これらの共通の課題は、「ロールにかかわらずメンバー同士が、互いをよく知っているか」という当たり前のことをチームがどれだけできているか、時間を割けているか、ということかなと思います。メンバーのスキルセットをはじめとして、ときには「お子さんがまだ小さいくて送り迎えが必要」とか「今日は花粉症がひどくてだるい」など、スキルセット以外にも、仕事をするにあたり影響を及ぼす要素はたくさんあります。した個人的な事情、というのはお互いに開示するまでそれなりに時間と信頼関係が必要なものなので、明示的な場や時間を取ることが必要だろうな、と感じました。この方法の1つとして、アンゲームというのを最近、メンバーから教えてもらい、利用したのでご紹介します。非常に簡単なルールと準備で、お互いの胸の内を話してゆく仕組みになっているゲームです。プロジェクトの開始時や定期的なふりかえりで活用なさってはいかがでしょうか。おっぴー、男:30代)まとめ私のテーブルのまとめをざっくりと上げますと以下の内容です。Keepクラウドを利用するにあたって、AWSとHerokuを活用するパターンをある程度提示できたかと思います。エンジニア主体で進む(Heroku)か、DevOpsで進む(AWS)かインフラエンジニア(サーバ側の事情に詳しいという大前提)の枠をチームに設ける(AWS)か、チームは全員開発に専念し、アドオンで解決する(Heroku)かまた、ESM様とFLECTの開発事例がどうなっているのかも情報交換が出来たかと思います。開発の基盤は、案件の引き合いの違いによるところが大きいという点FLECT側はForce.comとのインテグレーションが多いのでHerokuを利用する事が多いその代わりFLECTの開発は割りとバリエーションがある(開発言語は雑多)ESM様はほぼRuby(0.5%ほどNode.js)Problem課題点として以下の点が挙げられました。議論の中心が定められなかった。(テーブルオーナーである@ucmskyの力不足です。)IaasとPaasの使い分けに関してコストの観点での境界がどのあたりになるのかの掘り下げが足りなかった。(@ucmskyの個人的な見解)@koic様の「SIとインフラがどう絡むか?」の質問には上手く掘り下げることが出来なかったこと。Try個人的にやってみたかったこととして、オンプレのトラブル事例に対して、クラウドでどのような解決が可能かというディスカッションをやってみたかったです。(某ショッピングサイトのトラブルの事例を後になって思い出したので時既に遅しでしたが。逆にもしオンプレでなければならない事例があればその掘り下げも。最後に永和システムマネジメントの方々、ありがとうございました。一緒に勉強会を開催させていただきたく思います。Macの環境構築をしてみました。ご無沙汰しております、おっぴーです。Macの環境作成方法について書いてみたいと思います。Xの環境がほしい!ということはほとんどありません。XにNode.jsの開発環境を作りたい」という要望がでてきたためVirtrualBoxを利用した環境構築をしてみました。Xを起動してライセンス的に問題ないのかVirtualBoxを動かすためのisoファイルの作り方VirtualBoxの設定と起動方法についてご紹介します。Storeからダウンロードしたインストーラーを利用して、Mac上で2つまで環境構築をして良い、となっています。下記が日本語の引用文です。お客様が所有または管理する各Macコンピュータの仮想オペレーティングシステム環境内で、Appleソフトウェアの最大2つの追加コピーまたはインスタンスをインストールし、使用し、稼働させることができます。目的として行うことができます。VirtualBoxを動かすためのisoファイルの作り方これらの情報はいろいろあるのですが、下記が一番詳しい手順でした。Capitanのインストーラーをダウンロードします。Capitan.app」という名前で作成されます。ちなみにファイルの大きさが6Gもあるので、ダウンロードが終わるまで気長に待ちましょう。つぎに、isoファイルを作成する作業に入ります。各コマンドの詳しい内容は上記のURLを見て下さい。ここではざっとコマンドをご紹介します。ElCapitan.iso以上で、VirtualBoxでインストールに利用するisoファイルの作成は完了です。個人的なハマりどころは、VirtualBoxの設定です。チップセットの設定を、PIIX3に変更することです。http://apple.stackexchange.com/questions/198737/install-el-capitan-in-virtual-box-for-testing-purposes設定を変えておかないと、VirtualBoxを起動しても、インストールが始まりませんでした。設定方法は、画像を参考にしてください。作成したisoファイルを設定した後、起動したらあとは通常のインストール方法と同様です。AppleIDの認証がとおることは確認していません。AppleIDが連携できるかは、適宜、確認してみてください。Xからインターネットの接続ができない、という事象にも遭遇しました。原因はしらべていませんが、その際は、システム環境設定→ネットワーク→アシスタント→診断を選択し、ネットワーク診断をすると正常にインターネットに接続できるようになりました。Capitanを動作させられます。需要があるのか謎ですね。Macの環境構築をしてみました。(金)JavaScriptの書き方をいろいろと試してみたこんにちは、三宅です。1月からのプロジェクトで開発しているアプリケーションでは、サーバサイドもクライアントサイドもJavaScriptを採用。その中でソフトウェアアーキテクチャやコーディングスタイルなど、いろいろなことを試してみました。アプリケーションの特徴コンテンツ管理がメインユースケースのアプリケーションです。現時点ではそれほど複雑な構造にはなっていませんが、タグ付けやユーザやロールに応じたアクセス権限を実装することが将来的にあるかもしれない、というようなものです。開発に際して、以下の方針を立てました。ドメイン層を明確に分離するアプリケーションで扱う概念をモデルとして表現するドメイン層は特定のフレームワークやインフラに依存しないクラスベースで記述するドメインモデルをクラスとして宣言的に定義したいECMAScript2015(ES6)でクラス定義や継承などが直感的に記述できるようになったためサーバサイドとクラインとサイドは同じモデルを利用するバリデーションなどはモデルに持たせ、それらのコードが分散することを防ぐまた、一般的なことではありますが、できるだけコードの重複を防ぐ、外部の状態に依存するコードを書かない、ということを意識しました。フレームワークやミドルウェアMongoDB、Express、AngularJS、Node.jsといういわゆるMEANスタックを採用しました。ORMとしてMongoose、テンプレートエンジンにはjadeを利用しています。コードは基本的にES6で記述し、サーバサイドはBabelを用いてファイルごとにES5に変換、クライアントサイドはBrowserifyを利用し、画面ごとにファイルを生成するようにしました。ビルドタスクやディレクトリ構成などは、Nodeyardをほぼそのまま利用しています。試したこといろいろ少しいろいろなレベル感の話が出てきてしまうかもしれませんが、開発の上で試してみて良さそうだったことを書いていきます。constでの変数宣言ES6では「let」と「const」という新しい変数宣言の方法が追加されました。参考letとconstはブロックスコープです。letは再代入が可能、constは再代入が不可能な変数となります。可能な限りconstを用いることで、意図しない値の再代入を防ぐことができます。varではなくletを用いることで、JavaScript特有のfor文の中などで宣言した変数の意図しない挙動を防ぐことができます。繰り返し処理は基本的にイテレータを使っているので、そこまでスコープを意識する機会はありませんが。アローファンクションの利用アローファンクションという記述で関数を宣言できるようになりました。1;};この記述は単なる「function」のショートハンドではなく、「this」のスコープがレキシカルスコープになるという大きな違いがあります。JavaScriptのfunction内のthisはダイナミックスコープで、呼び出し元によって参照先が変わるという大きな特徴がありました。アローファンクションを用いることで、例えばクラス内で定義した関数内のthisは常にクラスインスタンスになるため、挙動を予測しやすいコードになります。オブジェクトリテラルの拡張オブジェクトをリテラルで作成する際の構文が拡張されました。参考その中でも、変数を設定する際のショートハンドを多用しました。};上記のparamsは、以下のオブジェクトの宣言と同じです。password};変数名を何回も書く必要がなく、タイポの可能性を低減することができます。定義したモデルの拡張モデルをクラスとして定義するのですが、画面表示名の取得メソッドなど、ビジネスロジック以外のメソッドが欲しくなることがあります。そのようなメソッドはコアとなるクラス定義とは別に行うようにしました。SwiftのExtensionsのようなイメージです。${this.name}`;};やっていることは、従来のJavaScriptでもあったプロトタイプ拡張です。上記のように整理することで、コアのコードに特定の環境のみでしか利用しないメソッドを含めないようにすることができると考えています。共有するモデルに対してシリアライザとデシリアライザを追加し、サーバでのレンダリング時に設定した初期値をブラウザの上で復元できるようにしました。テンプレートをレンダリングする際に、以下のように初期値を渡すようにしました。初期値を代入する際に、XSSを防ぐためにエスケープしてレンダリングするようにしています。今回はAngularJSを利用しましたが、Reactのサーバサイドレンダリングでも同様に初期値を渡すことができると思います。渡された初期値をでシリアライズして利用します。User.deserialize(window.__INITIAL__.user);今回はモデルごとに定義しましたが、シリアライザは少し工夫すれば汎用的な関数を作れそうな気がします。MongooseのModelの継承Mongooseには、discriminatorというModelの継承を行うための機能があります。functionこの機能を用いて、Userというモデルに対してManagementUser、SubscriptionUserのようなユーザの種類に応じたサブタイプを定義しました。実際に保存されるデータにはサブタイプを識別するための項目が追加されるだけなのですが、サブタイプを宣言的に定義することができること、サブタイプを指定したクエリを実行できる点で採用しました。インスタンスが特定のクラスのオブジェクトであるかの判定あるクラスのオブジェクトをインスタンスを返却するメソッドがあり、そのインスタンスがどのサブクラスのオブジェクトであるかによって、処理を分けたいというような場面。ES6のクラス定義は実際には継承とプロトタイプチェーンのシンタックスシュガーであるため、instanceofが使えます。プロジェクトでは、インスタンスを判定するための関数を定義して利用しました。ApplicationErrorのような独自のエラーを定義して、そのエラーの時だけ処理を変えたい、というような場面。クラス継承ができるのなら...と以下のように書いていたのですが、instanceofでErrorのインスタンスとしか判断することができませんでした。ApplicationError」でfalseが返されました。暫定処理として、typeプロパティを生やしてそれで判断するようにしましたが、この部分は少し調べて見る予定です。試してみたことを書きましたが、やはりJavaScriptではイミュータブルで型に基づくプログラミングには限界がある...という印象です。継承によるサブクラスの利用はある程度使えるのですが、多重継承ができないこと、インタフェースの定義ができないことが、大きな足かせになります。そのようなプログラミングスタイルを取るのであれば、TypeScriptを採用した方がいいということを実感しました。クライアントサイドとサーバサイドでのオブジェクトの共有で、シリアライズする際にコンストラクタなどの情報を持っていないと、デシリアライズする際にサブクラスまで復元できないという問題もありました。今回はその部分は妥協して、基底クラスのオブジェクトとして復元して利用するような形をとりました。サーバサイドだけであれば、TypeScriptで型に基づくたプログラミングができるのですが、クライアントサイドでもコードを共有するようなパターンだと、パラメータのみのインタフェースを定義し、それに準拠したオブジェクトを処理する関数を用意する、という方式の方が楽かもしれません。今後もそのあたりはいろいろと試してみたいと考えています。パート2こんにちは、なかやまです。最近お仕事でCloudSearchを利用する機会がありました。CloudSearchはAWSが提供する検索サービスになります。前回もご紹介したのですが、もう少し躓いたところがあるのでお話させてください。複雑な検索もできるよクエリパーサーは4つ。Solrを知らなかったのですが、Solrを使っているシステムは移行が簡単そうにみえますね。Booleanとして使いたかったものは、リテラル型にtrue,falseとか0,1を入れて対応しました。テキスト型にはそれぞれ言語設定ができるよ。ドキュメント消したいときはどうするの?バッチでdeleteのJSON投げればOKCloudSearch上はドキュメントIDで一意になるように指定します。アップロードはcsvでできるの?できないの?コンソール&コマンドラインツールからはcsvOK。ドキュメントバッチはJsonかXML形式だけです。1回の送信サイズ最大5Mになるように調整しよう。https://docs.aws.amazon.com/ja_jp/cloudsearch/latest/developerguide/preparing-data.html#creating-document-batches項目の設定でreturnにチェックをはずすと、コンソール画面から叩いても、結果がわからなくなったよ。表示項目として利用しないものだったので、returnのチェックを外した所コンソール画面から検索したときに値の確認ができなくなりました。検索結果のjsonには、returnにチェックの入った項目しか返却されません。コンソール画面からは確認できるのではないかと、思い込んでマシタ。検索条件に指定することで値が設定されていることは確認できましたが、まずは全部returnチェックをして正しく登録されていることを確認してから、returnチェックを省いたほうがよかったかな。項目にnullって登録できないの?登録するjsonにて項目をブランクで登録した所、検索結果からは項目自体が抹消されてまいした。呼び出し側では項目がない場合の制御が必要ですね。特定の項目だけ更新したかったのに毎日特定の列だけ更新したいことがありました。よし、特定の項目だけ更新すればバッチの時間短縮だよね!と思っていたのですが、どうやら特定の項目だけ更新はできないようです。選択したフィールドだけを更新することはできません。ドキュメントは新しいバージョンで上書きされますhttps://docs.aws.amazon.com/ja_jp/cloudsearch/latest/developerguide/preparing-data.html#adding-documents日本語検索の仕様がわかりにくい今までテキスト検索といったら、SQLのLIKE条件を使う程度でした。CloudSearchでは項目ごとに言語設定ができるんです。その設定によって、検索結果が変わってきます。京都で検索すると京都しかhitしないものどうやってインデックス作ってるの?1.トークン分割・・・スペース・タブ・空白文字・ハイフン・記号(@)でも分割。下線、コロン、カンマは分割されない。キャメルケースも分割されず。3.ステミング・・・インデックスに含まれる用語の数を減らす4.ストップワード・・・インデックス作成時にも検索時にも無視される単語5.シノニム・・・検索しているデータ内に存在する用語に対してシノニムを設定できます※辞書の設定はコマンドからhttp://docs.aws.amazon.com/ja_jp/cloudsearch/latest/developerguide/text-processing.html検索するときにも同じテキスト処理をかけて検索するそうです。プレフィックス検索だと検索用語でテキスト処理をしないそうです。完全一致のみ利用するのであれば、リテラル型で定義すればよいそう。ドキュメント登録にどのぐらい時間がかかるの?アップロードするドキュメントのサイズとインデックス作成する項目数によります。今回ネックになったのは送信元となるjsonファイルの作成にかかった時間でした。cloudsearchに投げる前ですね。jsonファイルができたら、並列投入することでオートスケールしてくれます。公式ドキュメントには数十秒〜数分とかいてますが、そのとおりだと思います。(金)Crystal勉強会でFrostネタで登壇し、Herokuにデプロイするまでを纏めるドーモ、読者=サン、ペンギン@ucmskyです。ご無沙汰してますが、先日1月22日にクックパッドさんで、第3回Crystal勉強会が開催され、ありがたいことに15分のセッションの枠をいただくことになりました。実際は20分以上喋り尽くしました。magazineさんに記事にしていただきました!いえーい。実践的なテーマの発表も増えた「東京Crystal勉強会」第3回の様子をレポート!私のセッション資料は、こちらです。Uchida「バグを見つけたら、”俺が直す”くらいのつもりで触れ」と僕はキメ顔でそう言った。後、「Kemalはいいぞ」Crystalの簡単な紹介ここでざっとCrystalについて完結に説明させていただきます。平たく言うと、Rubyライクな言語なのですが、以下の特徴を持っています。ビルドしてLLVMバイナリを出力する静的型付けマクロによるコードジェネレート文法に関してはとりあえず以下の解説に目を通していただけると感覚は掴めると思います。入門ご覧のとおりのRubyライクです。Rubyとの大きい相違点として、メタプログラミングで使用するeval系のメソッドなどが使えなくなっています。(ですのでメタプログラミングRubyで記載されている内容になるともう全く、RubyとCrystalは別物と言って過言ではないです)ただ、とりあえず動かしてみるような場合に関しては、Rubyの知識でも概ね問題はないと思います。(実際に僅かな読み替えで対応可能でした)尚、去年のRubyKaigi2015でもCrystalを扱ったセッションもありました。LanguageHeroku社の中の人の@leinweberさんによるCrystal概論の発表です。ぶっちゃけ私がRubyKaigi2015のLTのCFPに送った内容とほぼ全部被りました。その他細かい点の解説、対応しているプラットフォームの情報、更新履歴などは公式サイトや、日本コミュニティのサイト(ドキュメントなどは日本語に翻訳しています)に記載されています。Crystal公式Crystal-JPなお、Latestバージョンは2016年2月4日時点で0.11.1となっています。Crystalを取り巻くツールツールの開発も活発に行われています。Webで公開されているもので有志の人が纏めた一覧がこちらです。awesome-crystalDBアクセス用のツール、特にpostgresqlへのアクセスツールは前述のRubyKaigiで登壇された、@leinweberさんが作られました。Railsライクなツールも出始めています。Kemalシンプルな構成になっているフレームワークですが、現時点でも高い品質となっています。実際に公開されているアプリ開発にも使用されており、第3回Crystal勉強会でもWebアプリ開発事例としてKemalを使用したアプリが紹介されていました。思うのですが、幾つか候補はあります。一つがAmethyst、もう一つが今回取り上げるFrostです。どちらもまだバージョンは0.2を超えるかどうかという始まったばかりのプロジェクトです。Frostを取り上げた理由については全体的な枠組みが出来つつあるActiveRecordライクなツールがある程度使えるという感じです。Frostチュートリアルは同じリポジトリのguidesに同梱されています。Latestバージョンは2016年2月4日時点で0.2.1となっていますが、Crystal本体の破壊的変更(コアライブラリのファイル名やファイルパスがよく変わるので)の影響で動作しなくなっています。0.10.2で確認している以下のリポジトリをcloneすると取り敢えず動きます。frost_sampleチュートリアルでまだ書かれていない部分で、私が確認した点は以下のとおりです。以下のディレクトリなどが生成されます。Uchidaパッと見た感覚では、大枠の構想は固まっているように見えます。どこに何を配置するかは、そのままRailsの仕様に沿うようです。Routing公式サンプルでは以下のRoutingの設定が記載されています。(中略)endshowとindexを使用していますが、onlyの設定を外すとエラーになります。(まだ幾つかのメソッドが実装されていないのが原因)幾つか試した結果、newとcreateを追加することは出来ました。(中略)endActiveRecordある意味一番気になる箇所となる、ActiveRecord的なO/Rマッパーの実装ですが、試した結果、検索系の幾つかと作成処理は使用可能でした。FrostのDB処理を行っているコードを見る限りでは、削除系も定義はされていました。コードを見る感じでは以下の使い方は出来そうですが。Hoge.find(id)hoge.deleteHerokuで動かしてみる勉強会までに間に合わなかったのですが、Herokuで動かすことも出来ます。いうかFrostやKemalでも使えるように拡張build-packを作りました。(まだまだ動作が不安定ですが)heroku-buildpack-crystal作成にあたり、Elixirのビルドパックを多大に参考にさせていただきました。ぶっちゃけElixirのbuildpackの8割コピペですがheroku-buildpack-elixir作り始める時点では実はビルドパックの構造を殆ど知らなくて、公式のビルドパックに少しずつ設定を足しながらの作業でした。使い方等は上記リポジトリのREADMEに記載していますが、ここでビルドパックにはどういう設定を記載すればいいのか簡単に説明します。作り方の記載の全てはHeroku公式ドキュメントに記載されています。API本ブログでも過去にビルドパックの作り方について解説している記事があります。(かれこれ2年以上前の記事ですが)Herokuにバイナリを組み込むbuildpackを作成する使用言語はbashであれば問題無いです。別にbashでなくてもよく、極端な話、herokuのDyno上で実行可能な言語であれば何でも構いません。実際に公式のRubyのビルドパックではRubyが使用されていたり、Groongaのビルドパックも同様にRubyで記載されています。heroku-buildpack-rubyheroku-buildpack-groongaビルドパックに必須となるファイルは以下の3つです。detectcompilerelease上記3つのファイルをのカレントのbinディレクトリ以下に設置します。detectこのビルドパックを適用する対象のプロジェクトかどうかを判断します。Rubyの公式ビルドパックを参考にしますと、こんな感じになっています。1fiRubyのプロジェクトであるなら、ビルドパスのカレントにGemfileがあるはず、という判定をしています。(ここでGemfileのパスに指定している$1がビルドパスを表しています(後述))Crystalだとこれをshard.yml(ライブラリ管理ツールshardsが読み取る設定ファイル)に置き換えます。(v0.8以降のデファクト)compile多分一番処理が多くなる箇所であり、ビルドパックの中心となるファイルです。ファイル名の通りプロジェクトのビルドを行うファイルですが、ビルドに必要となるコンパイラ、インタプリタ本体のダウンロード、ビルド、ビルド後の処理などは全てこのファイルで設定します。実行時に3つの引数が渡されます。環境変数の情報一覧を格納したディレクトリのパスビルドパスとはまさにアップロードするアプリが格納されるパスです。ビルド対象となるパスとなります。キャッシュパスはビルドするツールを格納するパスです。CrystalならCrystal本体をダウンロードしてここに格納します。Elixirの場合だとElixir本体とErlang本体、mixによってダウンロードされるパッケージなどもここに格納しています。最後に環境変数一覧が格納された環境変数のパスが渡されます。ここで言う環境変数とはHeroku側ですでに設定されている環境変数のことで、環境変数名の名前のファイルに環境変数の値が記載されたものが格納されたディレクトリとして渡されるようです。FrostやKemalを動かそうとする場合、大体のケースでDBアクセスが必要になりますので、Heroku側で標準で用意されているPostgreSQLを利用する場合などにこのタイミングでアクセス先のDBの情報を読み取ります。(Frostの場合、ActiveRecord的にDBのカラム名からメソッド名を解決している箇所があるので、ビルド時にDBにアクセスしに行けないとエラーになります)Crystalのビルドパックではだいたい以下の流れで処理を行っています。ユーザ指定のカスタムコンフィグを読み取るHerokuの環境変数を読み取るCrystal本体のダウンロードとインストールshardsによる関連ライブラリのインストールアプリのビルドビルド後に実行するコマンドがあれば実行(未実装)公式のCrystalのビルドパックでは使用するCrystalのバージョンがハードコーディングされていたので、異なるバージョンのCrystalを使う場合都度ビルドパックを書き直す必要がありました。それをユーザ指定できるようにしたかったので、これはこれで手間ですが、ビルドパスにHeroku用のビルドコンフィグファイルを用意してもらって(ちなみになければなくてデフォルトの設定が走ります)、それを読み取るようにしています。大体設定しないといけないのがCrystalのバージョンと、ビルドコマンドです。なんのファイルをビルドするのかも公式のビルドパックではハードコーディングしていました。app.crという名前だった気がしますが、その名前でファイルを作っていないとビルドできませんでした。この状態だとFrostと激烈に相性が悪いので(Frostだとビルド対象のファイル名はそのままプロジェクト名となる)それも変えたかったので。後は大体Elixirの流れをそのまま持ってきています。(Elixir固有の設定までベタ打ちしてたのは修正予定です)release一番最後に実行されるファイルです。push時にのみ実行されるので、ビルドパスに.profile.dディレクトリを作ってその中にbashスクリプトを設置しておいたほうが柔軟に運用できると思います。その他、Procfileがない場合の動作を設定できますが、Procfileで制御したほうがまず問題ないかと思います。複数のビルドパックを指定した場合は、一番最後に実行されたビルドパックのreleaseが実行されます。極端な話、このファイルに関しては設定があれば少し便利という具合です。@pine613さんに感謝を。RubyKaigi2015のLTのCFP提出するなど年末の行動力以外取り柄がなかった私ですが、初のLT以外のセッションで色々と緊張しっぱなしでした。次回も何かやりますのでよろしくお願いいたします。会場提供いただきましたクックパッド様、ありがとうございました。セッションが始まったらやたら表示が途切れてしまった中対応してくださった、@mirakuiさんと@rosylillyさんには感謝です!......元々いろいろケチってHDMIケーブルでつないでいたのをVGAアダプタに通してたのでマシンパワーが足りなさすぎでした。VGAケーブル用意しておきます。@zundanさん、ありがとうございました。PRくださった、@5t111111さんと@HKDnetさん、まともなテストもできてないポンコツアプリをいい感じにしていただいて感謝です!最後に、いっつもしょうもない質問に対応していただいているCrystal-JPコミュニティの皆様方、ありがとうございました。(金)Herokuが東京にやってきた!(正式に)ついに、「Heroku?東京リージョンで使えるよ!」と大手を振って言える時が来ましたね!ふむふむ。過去にもこの話題を紹介していましたねー。Enterpriseを利用されているすべての方は、東京リージョンを選択した運用が可能になるのです。