Skip to content
shunter1112 edited this page Aug 13, 2013 · 2 revisions

このチュートリアルはHerokuにデプロイされるClojureRingウェブライブラリについて扱って行きます。Herokuを使ったアプリケーションの開発や設計の仕方に関する一般的な情報は、Architecting Applications for Herokuを確認してください。

事前準備/前提条件

ローカルの開発環境の設定

始めに、Heroku Toolbeltをローカルにインストール します。これはあなたのHeroku command-line client、Foreman、そしてGitのバージョン管理システムへアクセスを確かなものにします。

一度インストールできると、herokuコマンドがシェルから使えるようになります。アカウントを作ったときに使ったE-mailアドレスやパスワードを使ってログインしてみます :

:::term
$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password (typing will be hidden):
Could not find an existing public key.
Would you like to generate one? [Yn] 
Generating new SSH public key.
Uploading ssh public key /Users/adam/.ssh/id_rsa.pub

エンターキーをおすとすぐに存在しているsshキーか新しいものをアップロードしてくれます。後でコードをプッシュするときに使います。

アプリケーションの作成

既に存在しているアプリケーションから始める人もいるかもしれませんが、もしそうでなければ、あなたに使ってもらえる簡単な"hello, world"のソースコードを用意しています :

src/hello/world.clj

:::clojure
(ns hello.world
  (:require [ring.adapter.jetty :as jetty]))

(defn app [req]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body "Hello, world"})

(defn -main [port]
  (jetty/run-jetty app {:port (Integer. port) :join? false}))

また、lein new heroku helloworldを実行することで、Herokuの環境で便利ないくつかの更なる便利な機能を持ったスケルトンプロジェクトを生成することができます。

project.cljの中での依存ファイルの宣言

HerokuはアプリケーションがClojureの物であるということを、project.cljファイルによって認識します。ここに、上で作ったClojure/Ringアプリケーションのためのporoject.cljの例があります :

project.clj

:::clojure
(defproject helloworld "0.0.1"
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [ring/ring-jetty-adapter "1.1.6"]]
  :uberjar-name "helloworld-standalone.jar"
  :min-lein-version "2.0.0")

ビルド用の生成物がバージョン管理に含まれてしまうのを防ぐために、以下のファイルを作成します :

.gitignore

:::term
/target
/pom.xml
/.lein-*
/.env

パブリックなリポジトリでは利用できない依存ファイルに依存しているプロジェクトは、プライベートなリポジトリにデプロイするのがいいでしょう。これをするための最も簡単な方法としてs3-wagon-privateLeiningenプラグインを使って、プライベートなS3のバケットを利用することです。

Procfileへのプロセスタイプの宣言

アプリケーションのルートディレクトリにあるテキストファイルであるProcfileを使って、Web Dynoを開始させるために何のコマンドを実行するべきかを明示的に宣言します。今回は、単体のClojure名前空間で実行する必要があります。

これは私たちのアプリケーションのためのProcfileです :

:::term
web: java $JVM_OPTS -cp target/helloworld-standalone.jar clojure.main -m hello.world $PORT

これは、1個のwebプロセスタイプと実行する必要のあるコマンドを宣言しています。"web"と付けることはここではとても重要です。これは、このプロセスタイプがHerokuのHTTPルーティングのスタックに積まれ、デプロイされた際にWebトラフィックを受け付けることを意味しています。

簡単な確認のために、ローカルではlein run -m hello.world 5000を使ってアプリケーションを実行することができます。もしくはインタラクティブな開発のために、replからサーバを起動することができます。

:::term
$ lein repl
[...]
user=> (require 'hello.world)
nil
user=> (hello.world/-main 5000)
2013-07-01 13:52:49.575:INFO:oejs.Server:jetty-7.6.1.v20120215
2013-07-01 13:52:49.627:INFO:oejs.AbstractConnector:Started [email protected]:5000
#<Server org.eclipse.jetty.server.Server@2f26f304>

アプリケーションが5000番ポートで立ち上がります。curlやブラウザで適切に動いているかを確認した上で、Ctrl-Cで終了します。

Gitへのあなたのアプリケーションの格納

今、私たちはアプリの中に3つの主要な構成要素を持っています。project.cljの中の依存関係ファイル、Procfileの中のプロセスタイプ、そしてsrc/hello/world.cljの中にある私たちのアプリのソースです。Gitに追加していきましょう :

:::term
$ git init
$ git add .
$ git commit -m init

Herokuへのアプリケーションのデプロイ

(Herokuの)アプリケーションを作成します :

:::term
$ heroku apps:create
Creating glowing-snow-27... done
Created http://glowing-snow-27.herokuapp.com/ | [email protected]:glowing-snow-27.git
Git remote heroku added

コードをデプロイします :

:::term
$ git push heroku master
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 710 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)

-----> Heroku receiving push
-----> Clojure (Leiningen 2) app detected
-----> Installing OpenJDK 1.6...done
-----> Installing Leiningen
       Downloading: leiningen-2.2.0-standalone.jar
       Writing: lein script
-----> Building with Leiningen
       Running: lein uberjar
       Retrieving org/clojure/clojure/1.5.1/clojure-1.5.1.pom from
           from http://s3pository.herokuapp.com/clojure/
       [...]
       Created /tmp/build_1y7nbplmlxu87/target/helloworld.jar
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size: 51.4MB
-----> Launching... done, v1
       http://glowing-snow-27.herokuapp.com deployed to Heroku

To [email protected]:glowing-snow-27.git
 * [new branch]      master -> master

アプリケーションへの訪問

Herokuにコードをデプロイしました、そしてProcfileの中にプロセスタイプを指定しました。今、あなたはHerokuに対してプロセスタイプを実行するための指示を出す事が出来ます。Herokuはdynoに関連づいたコマンドを実行することでこれを行います。dynoとはHerokuにおける基本的な構成要素の単位になっている軽量コンテナのことです。

webプロセスタイプが実行されているdynoがあることを確かめてみましょう :

:::term
$ heroku ps:scale web=1

アプリケーションのdynoの状態を確認することができます。このheroku psコマンドはあなたのアプリケーションの実行中のdynoをリストします :

:::term
$ heroku ps
=== web: `java $JVM_OPTS -cp target/helloworld-standalone.jar clojure.main -m hello.world $PORT`
web.1: up for 5s

ここにdynoが一つ走っています。

heroku openを使ってブラウザでアプリを確認することができます。

:::term
$ heroku open
Opening glowing-snow-27... done

Dynoのスリープと拡張

実行中のWeb dynoを一つだけ持っている事は、dynoが非アクティブになったあと1時間経つとスリープすることを意味します。これは再度立ち上がるときの最初のリクエストに対して数秒の遅れが発生することを意味します。後続のリクエストは通常通りに帰ってくるでしょう。

これを避けるために、web dynoを1個以上に増やすことが出来ます。例えば :

:::term
$ heroku ps:scale web=2

それぞれのアプリケーションごとに、Herokuは750時間のdyno無料利用時間を提供しています。2個のdynoで動いているアプリケーションは、月々のこの無料利用時間を超える可能性が高いので、増やしたものを戻してみましょう :

:::term
$ heroku ps:scale web=1

ログの確認

Herokuは、アプリケーションの内容物を実行しているすべてのdynoの出力ストリームから時系列イベントのストリームとしてログを扱います。HerokuのLogplexはこれらのイベントの全てをあつかう単体のチャネルを提供しています。

ログ用コマンドの一つを使って、実行中のあなたのアプリケーションの情報を見てみましょう。heroku logs を実行します。 :

:::term
$ heroku logs
2011-03-16T03:28:32-07:00 heroku[web.1]: Running process with command: `java $JVM_OPTS -cp target/helloworld-standalone.jar clojure.main -m hello.world $PORT
2011-03-16T03:28:37-07:00 app[web.1]: 2011-03-16 10:28:37.181:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
2011-03-16T03:28:37-07:00 app[web.1]: 2011-03-16 10:28:37.182:INFO::jetty-6.1.26
2011-03-16T03:28:40-07:00 app[web.1]: 2011-03-16 10:28:40.223:INFO::Started [email protected]:20184
2011-03-16T03:28:40-07:00 heroku[web.1]: State changed from starting to up

コンソール

Herokuでは、必要な時にスクリプトとそのためだけに実行されるアプリケーションであるone-off dynoの中で、heroku runを使って、コマンドを実行することが可能です。 あなたのアプリケーションの環境の中で実験のために、ローカルのターミナルでREPLプロセスを実行するためにこれを使います。

`heroku run lein repl`を実行することは、Leiningenによって提供される`repl`タスクの指定されたバージョンを使用します。
:::term
$ heroku run lein repl
Running lein repl attached to terminal... up, run.1
Downloading Leiningen to .lein/leiningen-2.2.0-standalone.jar now...
[...]
Clojure 1.5.1
user=> 

Leiningenは大きさの面からあなたのSlugに含まれないため、ここでは必要に応じてダウンロードされます。replはあなたのアプリケーションの名前空間を利用可能にします。例えば :

:::term
user=> (require 'hello.world)
nil
user=> (hello.world/app {})
{:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello, world"}

HerokuでのREPLの使用に関する更なる詳細についてはClojureアプリケーションのライブデバッギングの記事を確認してください。

One-off スクリプト

あなたは簡単な(一回限りの = one-off)Clojureスクリプトを、あなたがデプロイしたアプリケーションの中にそのスクリプトが存在している限り、上記と同じようにターミナルから実行することができます。コンソールに出力をして終了するような、簡単なスクリプトを作ってみましょう :

src/hello/hi.clj

:::clojure
(ns hello.hi)

(defn -main [& args]
  (println "Hello there"))

この新しいコードをコミットしてデプロイします :

:::term
$ git add src/hello/hi.clj
$ git commit -m hi
$ git push heroku master

one-off dynoの中で、heroku runを使ってこのスクリプトを実行します :

:::term
$ heroku run lein run -m hello.hi
Running lein run -m hello.hi attached to terminal... up, run.2
Hello there

SQLデータベースの使用

デフォルトでは、Clojureアプリケーションはデータベースを備えていません。これは、あなたがきっとRedisやCouchDBのようなNoSQLデータベースを使いたがるか、(上の私たちのサンプルアプリの場合のように)全くデータベースを使う必要がないと考えているからです。

もし、SQLデータベースがあなたのアプリケーションに必要になったら、明示的に要求をします :

:::term
$ heroku addons:add heroku-postgresql:dev

次のステップ

Clone this wiki locally