2022年3月6日日曜日

clojure cliプロジェクトをherokuで動かす


背景

clojureとはjvmなどで動くlisp系言語です。
herokuとはサーバーを気軽に立てれるwebサービスです。

clojureのライブラリ管理コマンドとしてはleiningenclojure cliなどがあります。
herokuはleiningenに対応しているもののclojreu cliに対応していないため、clojure cliのプロジェクトを動かす場合はひと工夫必要になります。

leiningenは先に登場したため利用例が多いですが、後に登場した公式が開発しているclojure cliを試したかったので、趣味のプロジェクトをclojure cliで作りherokuで動かしたかったのが今回の動機です。
試行錯誤したり助言をいただいたりしていくつかの方法が分かったので、備忘録として記事を残します。

使ったもの

  • herokuのアカウント
  • heroku cli
  • clojure cliで作ったプロジェクト
    clj-newを利用しました。

heroku/clojureを使う

buildpack設定: heroku/clojure

heroku/clojureを選びます。
プロジェクトのリポジトリのルートディレクトリにproject.cljがあれば標準で選ばれるはずですが、javaモードになった場合などは手動で変更が必要です。

設定画面からは Settingタブ -> Buildpacks で設定できます。




リポジトリをデプロイし、leiningenプロジェクトと認識させつつclojureコマンドを実行

clojureとして起動するとleiningenのビルド処理が走るため、それに必要なファイルがないとエラーが発生して起動に失敗します。

下記ファイルの配置でleiningenのビルドを終えれます。
  • project.clj
    defprojectを定義し、min-lein-versionを2以上に指定します。
    min-lein-versionが無いと、新し目のclojureインストール時にエラーになります。
    project.clj
    (defproject project-to-run-on-heroku "0.1.0-SNAPSHOT"
    :min-lein-version "2.0.0")
  • 内容は空で良いです。
    clojureコマンドを実行して依存ファイルをダウンロードしても、Procfile実行時はそのファイルが無い状態で実行されるため意味がありません。

上記の設定でleinとclojure cliが使える状態のアプリができるので、Procfileでアプリ起動に必要なコマンドを実行してください。

Procfile
web: clojure -M:run-mc

リポジトリをデプロイすると、leiningenの初期化 -> Procfileのコマンド実行 の順に処理され、アプリが起動します。

clojure cliを手動ダウンロードして使う

buildpack設定: java

project.cljが無いclj-newで生成したプロジェクトをデプロイすると、自動でjavaモードになるので設定は不要だと思います。
他のbuildpackにしている場合は、heroku/javaに変更してください。



リポジトリをデプロイし、Procfileでclojure cliをダウンロードして実行

下記のようなコマンドをProcfileで実行(clojureコマンドのバージョンは、必要に応じて更新してください)
Procfile
web: curl -O https://download.clojure.org/install/linux-install-1.10.3.1075.sh && \
bash ./linux-install-1.10.3.1075.sh --prefix ~/ && \
./bin/clojure -M:run-mc

リポジトリをデプロイするとProcfileが実行されてアプリが起動します。

ビルドしたjarを実行する

heroku cliにjavaプラグインをインストール

herokuの説明に従い、プラグインをインストールします。
heroku plugins:install java

このプラグインを利用してデプロイするとjavaモードになるので、buildpackの設定は不要です。

jarを作り、コマンドでそれをデプロイ

jarを作ります。
clj-newを利用して作ったプロジェクトはuberjar設定があるので、それを利用できます。
clojure -X:uberjar

jarが出来たらherokuの説明に従い、jarをデプロイします。
コマンドを実行するディレクトリにProcfileがあるとそれも一緒に送信されるため、jarの実行以外の処理を起動時に行いたい場合はそこに記述しつつ、不要な場合はProcfileを送信しないよう注意が必要です。
下記コマンドのcreated-your.jarとyour-heroku-app-nameは、ご自身のものに置き換えてください。
heroku deploy:jar created-your.jar -a your-heroku-app-name

includeオプションがあるので、jar以外に実行に必要なファイルがあれば、それを利用して送れます。
サーバーアプリであれば実行にpublicディレクトリやビルドしたjsファイルなどが必要になるので、それらを一緒にデプロイするときに便利です。
複数のファイルやディレクトリを一緒に送信したい場合は、「:」でパスを繋ぎます。
heroku deploy:jar created-your.jar -a your-heroku-app-name -i ./public:./out

コマンドを実行すると 関連ファイルの送信 -> Procfileがあるならそれの実行、無ければjarファイルの実行が行われ、アプリが起動します。

おわり

clojureのプロジェクトをherokuにデプロイするいくつかの方法を共有しました。
clojurescriptのビルドがherokuのアプリ起動時間60秒に収まらなずに利用を諦めかけていましたが、jarファイルの送信やinclude機能を利用したディレクトリの送信方法があり時間がかかるビルドは手元でできると分かったので、引き続きherokuを使えます。

参考

NodeJs app with Java on Heroku
Deploying Executable JAR Files
ビルド動作のオーバライド
clj-new
Heroku CLI Plugin for Java


変更履歴

2022.03.12
heroku javaプラグインで複数のファイルを取り込む際の記述方法が「:」繋ぎだったので、修正しました。

0 件のコメント :