跳至內容
GitHub 儲存庫 論壇 RSS 新聞訂閱

Heroku 建置套件

Brian J. Cardiff

在 2014 年底,第一個草稿Heroku Crystal 建置套件被創建了。這真是太棒了。能夠在 Heroku 堆疊中執行 Crystal 應用程式是個很棒的想法。

當我們持續開發語言、工具和標準函式庫時,圍繞 Crystal 的社群也成長了。許多人有興趣在 Heroku 中嘗試他們基於 Crystal 的 Web 應用程式。GitHub 上建置套件的網路圖相當大,特別是對於只是一堆 bash 指令碼來說!

然而,由於該方法的一些缺陷,建置套件未能與最新版本的 Crystal 保持同步;但現在這個問題已經解決了!耶!

雖然現在持續努力開發 Web 框架,但我們想分享使用 Crystal 建置套件在 Heroku 中部署 Web 應用程式的基本步驟,而無需任何額外的相依性。

建立 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。建置套件會使用此名稱來判斷要編譯的主要來源檔案: ./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 來終止程序。

Herokufy 它

目前專案對 Heroku 一無所知。若要開始使用,需要先註冊一個 Heroku 應用程式。最簡單的方法是透過 Heroku 工具帶

$ 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 會隨機指派一個連接埠號碼供應用程式使用。多虧了建置套件,這將在執行應用程式時透過 --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

建置套件將會

  1. 安裝最新的 Crystal 發佈版本。
  2. 透過 shards 安裝專案相依性。
  3. 在發佈模式中編譯主要來源檔案。
  4. 使用 --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 建置套件,只需fork 它。歡迎貢獻!