Heroku での Clojure アプリのデプロイ
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年05月07日(火)
Table of Contents
この記事では、既存の Clojure アプリを Heroku にデプロイする方法について説明します。
Heroku をはじめて使う場合は、「Heroku スターターガイド (Clojure)」のチュートリアルから始めます。
概要
Heroku 開発に役立ついくつかの便利な追加機能を有するプロジェクトスケルトンを生成するには、lein new heroku helloworld
と入力します。スケルトンプロジェクトの README.md ファイルには、含まれている内容と使用方法が記載されています。
アプリの最も重要な部分は、src
ディレクトリ内にあるアプリケーションのソースコード、ルートディレクトリの project.clj
ファイル、およびアプリのプロセスタイプを定義する Procfile です。データベースは Clojure アプリに対して自動的にプロビジョニングされませんが、必要な場合に簡単に追加できます。
Clojure アプリケーションのソースコード
アプリケーションソースコードを src
ディレクトリ内のフォルダに配置します。
project.clj
ファイル
Clojure の依存関係マネージャーでは project.clj
ファイルが使用されます。Heroku の Clojure サポートは、project.clj
ファイルがルートディレクトリに存在する場合にのみ適用されます。
パブリックリポジトリで使用できない依存関係に依存するプロジェクトは、依存関係をプライベートリポジトリにデプロイできます。これを行う最も簡単な方法は、プライベート S3 バケットを s3-wagon-private Leiningen プラグインで使用することです。
デプロイ時に AOT (事前コンパイル) を使用することを強く推奨します。これによってアプリの起動が速くなり、アプリが稼働する前に特定の種類のエラーがキャッチされるためです。次の project.clj
設定によってデプロイ時に AOT が適用されます。ただし、ローカル開発中は適用されません。
:profiles {:uberjar {:aot :all}}
Procfile
Procfile は、アプリケーションのルートディレクトリにあるテキストファイルです。このファイルを使って、プロセスタイプを定義し、アプリを起動するために実行するコマンドを明示的に宣言します。これは次のようになります。
web: java $JVM_OPTS -cp target/helloworld-standalone.jar clojure.main -m helloworld.web
これは単一のプロセスタイプである Web と、その実行に必要なコマンドを宣言しています。ここでは、Web という名前が重要です。これは、このプロセスタイプを Heroku の HTTP ルーティングスタックにアタッチし、デプロイ後に Web トラフィックを受信することを宣言しています。
Web プロセスタイプ内のコマンドは、PORT
環境変数に指定されているポート番号にバインドする必要があります。そうしないと、dyno は起動しません。
Procfile には追加のプロセスタイプを含めることができます。たとえば、キューからアイテムを取り出して処理するバックグラウンドワーカープロセスに対して追加で宣言できます。
アプリの設定は、環境変数として Procfile 内のコマンドにエクスポートされます。たとえば、heroku config:add JVM_OPTS=...
を実行すると、ここで使用される値が変更されます。
ビルド成果物を Git の外部に保持する方法
.gitignore
ファイルを作成することによって、ビルド成果物がリビジョン管理の対象に入らないようにします。標準的な .gitignore
は次のとおりです。
/target
/pom.xml
/.lein-*
/.env
コンソール
Heroku では、heroku run
コマンドを使用して、One-off dyno (必要な場合にのみ実行するスクリプトおよびアプリケーション) を実行できます。このコマンドを使用して、アプリの環境で試行するためにローカルターミナルにアタッチされた REPL プロセスを起動します。
heroku run lein repl
を実行すると、Leiningen によって提供される repl
タスクの簡素化されたバージョンが使用されます。
$ 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 により、アプリの名前空間が利用可能になります。たとえば、次のようになります。
user=> (require 'hello.world)
nil
user=> (hello.world/app {})
{:status 200, :headers {"Content-Type" "text/plain"}, :body "Hello, world"}
One-off スクリプト
ターミナルにアタッチされた One-off Clojure スクリプトは、このスクリプトがデプロイ済みのアプリ内に存在する場合は同様に実行できます。コンソールに出力して終了する小さいスクリプトを作成してみてください。
src/hello/hi.clj
(ns hello.hi)
(defn -main [& args]
(println "Hello there"))
heroku run
を使用して、One-off dyno 内のスクリプトを実行します。
$ heroku run lein run -m hello.hi
Running lein run -m hello.hi attached to terminal... up, run.2
Hello there