Heroku Buildpack
2014年末に、Crystalのための最初のドラフトが作成されました。HerokuスタックでCrystalアプリを実行できるようになるのは素晴らしいアイデアでした。
言語、ツール、標準ライブラリの開発を続ける中で、Crystalを取り巻くコミュニティは成長しました。多くの人がHerokuでCrystalベースのウェブアプリを試すことに関心を持っていました。このBuildpackのGitHub上のネットワークグラフは、bashスクリプトの集まりにしては非常に大きいです!
しかし、アプローチにいくつかの欠陥があったため、BuildpackはCrystalの最新バージョンに追いつくことができませんでした。しかし、それは今解決されました!やった!
現在、ウェブフレームワークの開発努力が続けられていますが、追加の依存関係なしにHerokuにウェブアプリケーションをデプロイするためにCrystal Buildpackを使用する基本的な手順を共有したいと思います。
Crystalプロジェクトの作成
既にCrystalがインストールされていることを前提としています。
crystal init app
を使用してアプリを作成します。
$ crystal init app heroku101 create heroku101/.gitignore create heroku101/LICENSE create heroku101/README.md create heroku101/.travis.yml create heroku101/shard.yml create heroku101/src/heroku101.cr create heroku101/src/heroku101/version.cr create heroku101/spec/spec_helper.cr create heroku101/spec/heroku101_spec.cr Initialized empty Git repository in /Users/bcardiff/Work/Manas/crystal/heroku101/.git/ $ cd heroku101/
注記:投稿の残りの部分では、すべてのコマンドがheroku101/
ディレクトリから実行されます。
shard.yml
ファイルは、プロジェクト名をheroku101
として宣言します。これは、Buildpackがコンパイルするメインソースファイル(./src/heroku101.cr
)を決定するために使用されます。
$ cat shard.yml name: heroku101 version: 0.1.0 ...
シンプルなHTTPサーバーを作成するには、src/heroku101.cr
ファイルを編集し、次の内容を追加します。
# file: src/heroku101.cr
require "http/server"
bind = "0.0.0.0"
port = 8080
server = HTTP::Server.new(bind, port) do |context|
context.response.content_type = "text/plain"
context.response << "Hello world, got #{context.request.path}"
end
puts "Listening on http://#{bind}:#{port}"
server.listen
プログラムのビルドと実行
$ crystal src/heroku101.cr Listening on http://0.0.0.0:8080
http://0.0.0.0:8080でブラウザを開きます。
Ctrl+C
を押してプロセスを終了することで、サーバーを停止します。
Heroku対応にする
現時点では、プロジェクトはHerokuについて何も知りません。開始するには、まずHerokuアプリケーションを登録する必要があります。最も簡単な方法は、Heroku Toolbeltを使用することです。
$ heroku create --buildpack https://github.com/crystal-lang/heroku-buildpack-crystal.git Creating app... done, ⬢ sleepy-thicket-16179 Setting buildpack to https://github.com/crystal-lang/heroku-buildpack-crystal.git... done https://sleepy-thicket-16179.herokuapp.com/ | https://git.heroku.com/sleepy-thicket-16179.git
上記のコマンドは、ランダムなアプリ名を生成します。アプリ名最初から指定する方法については、ドキュメントを確認してください。
デプロイする前に、小さな変更を加える必要があります。Herokuは、アプリで使用されるポート番号をランダムに割り当てます。Buildpackのおかげで、アプリケーションの実行時に--port
オプションでこれが通知されます。
そのため、src/heroku101.cr
の先頭にrequire "option_parser"
を追加し、port
変数のデフォルト値を次のようにオーバーライドします。
OptionParser.parse! do |opts|
opts.on("-p PORT", "--port PORT", "define port to run server") do |opt|
port = opt.to_i
end
end
完全なsrc/heroku101.cr
は次のようになります。
# file: src/heroku101.cr
require "http/server"
require "option_parser"
bind = "0.0.0.0"
port = 8080
OptionParser.parse! do |opts|
opts.on("-p PORT", "--port PORT", "define port to run server") do |opt|
port = opt.to_i
end
end
server = HTTP::Server.new(bind, port) do |context|
context.response.content_type = "text/plain"
context.response << "Hello world, got #{context.request.path}"
end
puts "Listening on http://#{bind}:#{port}"
server.listen
--port
オプションを使用してビルドおよび実行するには
$ crystal src/heroku101.cr -- --port 9090 Listening on http://0.0.0.0:9090
または、ローカルで最適化されたリリースをビルドし、次のように実行します。
$ crystal build src/heroku101.cr --release $ ./heroku101 Listening on http://0.0.0.0:8080 ^C $ ./heroku101 --port 9090 Listening on http://0.0.0.0:9090 ^C
デプロイ!
アプリを公開する準備ができたら、通常の方法でgit push heroku master
を使用してデプロイします。
$ git push heroku master Counting objects: 22, done. Delta compression using up to 8 threads. Compressing objects: 100% (17/17), done. Writing objects: 100% (22/22), 2.85 KiB | 0 bytes/s, done. Total 22 (delta 3), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Fetching set buildpack https://github.com/crystal-lang/heroku-buildpack-crystal.git... done remote: -----> Crystal app detected remote: -----> Installing Crystal (0.17.3 due to latest release at https://github.com/crystal-lang/crystal) remote: -----> Installing Dependencies remote: -----> Compiling src/heroku101.cr (auto-detected from shard.yml) remote: remote: -----> Discovering process types remote: Procfile declares types -> (none) remote: Default types for buildpack -> web remote: remote: -----> Compressing... remote: Done: 289.4K remote: -----> Launching... remote: Released v3 remote: https://sleepy-thicket-16179.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy.... done. To https://git.heroku.com/sleepy-thicket-16179.git * [new branch] master -> master
Buildpackは次の処理を行います。
- 最新のCrystalリリースをインストールします。
- Shardsを使用してプロジェクトの依存関係をインストールします。
- リリースモードでメインソースファイルをコンパイルします。
--port
オプションを使用してWebサーバープロセスを実行します。
Crystalバージョンの指定
異なるCrystalバージョンを使用する場合は、crenvの規則に従って、目的のバージョンを含む.crystal-version
ファイルを作成します。
$ echo '0.17.1' > .crystal-version
.crystal-version
の変更をコミットしてデプロイします。
$ git push heroku master Counting objects: 3, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 301 bytes | 0 bytes/s, done. Total 3 (delta 1), reused 0 (delta 0) remote: Compressing source files... done. remote: Building source: remote: remote: -----> Fetching set buildpack https://github.com/crystal-lang/heroku-buildpack-crystal.git... done remote: -----> Crystal app detected remote: -----> Installing Crystal (0.17.1 due to .crystal-version file) remote: -----> Installing Dependencies remote: -----> Compiling src/heroku101.cr (auto-detected from shard.yml) ...
これで、(0.17.1 due to .crystal-version file)
という説明が表示されます。
最新のCrystalバージョンにアップグレードする準備ができたら、ファイルの内容を更新するか、削除して再度デプロイします。
コードを見せてください!
使用されているサンプルソースコードはすべてhttps://github.com/bcardiff/sample-crystal-heroku101にあります。
Crystal Buildpackに貢献するには、フォークしてください。貢献は大歓迎です!