今回はHerokuでJavaのWebアプリを動かしてみます。
HerokuはいわゆるPaasで、アプリケーションの開発と運用を手軽に行うことができます。
必要なサービスを手早く立ち上げて、アクセスが多くなって来れば簡単にスケール・アウトすることも可能ですが、無料の枠の中でも検証やお勉強は十分に可能ですので、アカウントを作って、開発の手順を学んでおくことにしました。
特に、OAuth認証のCallbackは、Webサービスを利用するうえでいろいろなところで登場しますが、外部(インターネット上)のサーバがあった方が便利なので、必要になったときにすぐに構築できる手順を把握しておきたいという狙いもあります。
Herokuアカウントの作成
まずは、無料アカウントを作成します。
メアドとパスワードを設定するだけですね。
アカウントができると、「最初のアプリを作りましょう!」といった感じの画面が表示されます。
ここでJavaを選択すると、「https://devcenter.heroku.com/articles/getting-started-with-java#introduction」から、入門用チュートリアルを始めることができます。このチュートリアルでは、Herokuでの開発を一通り体験して、コマンドラインやツールの使い方を学ぶことができます。
初めてのHerokuなので、私もここからスタートすることしました。
環境準備
herokuで、このgetting startedやJavaでの開発を進めるには、以下のアプリがあると便利です。
- JDK1.8
- git・・・herokuへのアプリのデプロイに必要
- Maven・・・依存するライブラリのセットアップやjarやwarファイル等へのアーカイブを行う
※JDKは、Oracleからダウンロードしてインストールします。PC上複数のJDKが混在すると場合、ちゃんとJDK1.8にならない場合がありますが、そんな時はこの記事「JAVA_HOMEが効かない!?複数のJDKを切り替えて使うときの問題点」を参考にしてください。
※gitは無くても、後程インストールするheroku CLI(toolbelt)と一緒にイントールもできます。むしろ、gitはすでにインストールされていることが多いかもしれません。ただ、ログインIDとパスワードが既存んgitユーザとは異なるので、heroku用にgitを使う際にエラーが出ることがあります。その時の対処法は「Herokuにアプリをpushしたときにエラーが出る場合の対処法」を参考にしてください。
Heroku用開発ツールをセットアップ
最初に行うのは「Heroku Toolbelt」のダウンロードとインストールです。Toolbeltは、Herokuで開発を行うために必要なコマンドラインツール(Heroku CLI)をまとめてインストールしてくれるアプリで、Herokuへのアプリのデプロイに必要なgitなども含まれます。
これをインストール後、「heroku」コマンドが使えるようになります。早速コマンドプロンプトを起動し、「heroku login」コマンドで、herokuにログインしましょう。
set HTTPS_PROXY=https://proxy.server.com:portnumber ・・・proxy背後にいる場合
heroku login
Enter your Heroku credentials.
Email: xxxx@xxxxxx.xxx
Password:xxxxxx
シンプルなアプリを公開してみる
すごくシンプルなサンプルアプリを実際に公開して動かしてみることで、一通りの手順を覚えます。
git clone https://github.com/heroku/java-getting-started.git my_first_app
と入力すると、getting started用のサンプルアプリをgitから取得することができます。「my_first_app」は任意のアプリ名を自分で好きにつけましょう。すると、「my_first_app」というディレクトリにサンプルアプリがダウンロードされます。
git cloneすると、originとして上記のgitリポジトリが登録されていますので、下記コマンドでoriginを削除しておきます。
必須ではないですが、今後、このサンプルをひな形に、自由に改造していこうと思っているので、gettting startedとは関係ないアプリになるので。。
git remote -v
git remote rm origin
これで、最初のひな形ができました。
次に、そのひな形アプリをheroku上で動かすために、herokuに登録します。そのために、アプリケーションのルートディレクトリ「my_first_app」でherokuのcreateコマンドを使います。
heroku create
これにより、裏で以下のようなことが行われます。
- heroku上にアプリケーションができる。heroku createの引数でアプリ名が指定されていれば、重複がなければその名前でアプリが生成される。引数がなければherokuによってランダムにアプリ名付けられる。
- 同時にheroku上に新たにできたアプリのgitリポジトリが作られる。
- heroku上のgitリポジトリと、ローカルのgitが関連付けられる。(ローカルのgitのremoteとして、herokuという名称でheroku上のリポジトリが登録される。「git remote add heroku https://git.heroku.com/<アプリ名>.git」が発行されたのと同じ。)
次に以下のコマンドで、heroku上のリモートリポジトリのmasterブランチにローカルのアプリをpushして公開します。
git push heroku master
これにより、ローカルアプリがheroku上にデプロイされます。デプロイ時には、依存関係の解消やコンパイルなど、ローカルで行われるMavenタスクが同じように行われるようです。
デプロイに成功すると、最初のWebアプリが動いていることを確認できます。
heroku open
上記コマンドか、デプロイ時に最後に表示されるURLをブラウザで開くと、こんな画面が開きます。
アンプルのアプリでは、トップURLの後に「/hello」もしくは「/db」を付けることで、HelloWorldの画面とDBを使ったサンプルの画面を動かすことができます。
なんだかあっという間に動いてしまいましたね。とはいえ、なんで動いているのかを理解するのも大事なので、裏側で何が起こっているのかを少し見てみましょう。
公開したひな形アプリの全体像を解説
ここで、ローカルにあるアプリディレクトリのファイル構成を見てみましょう。
gitで取得したローカルのアプリディレクトリ配下には以下のようなファイルがあります。
簡単に重要なファイルを説明すると、
Procfile
web: java -jar target/helloworld.jar
という記述があります。
このアプリを起動するときに何が実行されるのかを定義しているファイルです。
webというのが重要で、URLに来たリクエストを「web」タイプのdynoに転送することを宣言しているみたいです。
dynoは軽量のLinuxのコンテナで、herokuでは実行単位として重要な概念です。プロセスのように振る舞うとありましたが、詳しいことはまた別の機会に。
Pom.xml
maven形式のアプリの依存ライブラリを記述しているファイル。
これでmavenによってアプリを構成、コンパイルしてデプロイできることになります。
さて、アプリケーションがwebというタイプのdynoによって処理されていることが分かったところで、
heroku ps:scale web=1
Scaling dynos... done, now running web at 1:Free
と打ってみましょう。これはwebタイプのdynoを「1」つで処理するということを意味しています。
だから、「heroku ps:scale web=0」と打つと、処理するdynoが0個なので、アプリのURLにアクセスするとエラーになってしまいます。
ローカルで開発、実行できるようにする
実際の開発は、ローカルのPCで行い、動作確認まで行ったうえで、OKであればherokuにgit pushして公開 といった流れになりそうですよね。なので、ローカルでも実行して確認できるようにしておきます。
アプリのディレクトリで
<mavenのディレクトリ>\bin\mvn clean install
とするとローカルでアプリをコンパイルできます。成功すると、アプリのディレクトリに「target」というディレクトリができるはずです。
「heroku local web」と打つと、ローカルでサーバが起動しますので、「http://localhost:5000」にアクセスして動作を確認できます。
heroku local web
[OKAY] Loaded ENV .env File as KEY=VALUE Format
03:32:31 web.1 | [Thread-0] INFO spark.webserver.SparkServer - == Spark has ignited ...
03:32:33 web.1 | [Thread-0] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:5000
03:32:33 web.1 | [Thread-0] INFO org.eclipse.jetty.server.Server - jetty-9.0.z-SNAPSHOT
03:32:34 web.1 | [Thread-0] INFO org.eclipse.jetty.server.ServerConnector - Started ServerConnector@47670500{HTTP/1.1}{0.0.0.0:5000}
Javaでは、開発とデプロイの容易さから「Webapp Runner」や「Jetty」を使うことが多いようですが、Tomcatに慣れている人も多いと思います。
今後、要勉強ですが、参考までにそのエントリを載せておきます。
Webapp Runnerで動かす手順
「https://devcenter.heroku.com/articles/java-webapp-runner」
内蔵TomcatでWebアプリを作る手順
「https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat」