とりあえずSpringBootアプリケーションをherokuで公開する
手順の全て
mkdir {てきとうななまえ}
cd {てきとうななまえ}
curl -O https://start.spring.io/pom.xml -d dependencies=web -d javaVersion=8
- Applicationクラス作成(後述)
git init
git add .
heroku create
heroku git:remote -a {createで作られたもの}
git push heroku main
9ステップ。これでgit push
のレスポンスメッセージに出てるURLにアクセスしたらhello
と表示されます。目指せ5分!
説明
書きたいところを適当に書いていきます。あ、herokuアカウントの作成とコマンドラインツールのインストールは済ませといてください。私はbrew
で入れてます。
この記事は現在に対する局所最適なので、バージョンなどは割愛します。 未来にこの記事のバージョンに合わせて動かすより、やりたいときにその時点での最新のやり方でやるのがいいと思います。 どうせherokuの挙動変わったらバージョンなんぞ合わせられないし。
curl...
Spring Initializr です。ブラウザでも使えますけど私はもっぱら curl
で叩いてます。
詳しくは SpringBootのプロジェクトを作成する - 日々常々 とか。
普段はGradle使っていますが、今回はMavenを選択。
これは plain jar
がSpringBoot2.5からできるようになって、herokuのデフォルトだと *.jar
で起動しようとしてエラーになるため。
無効にするとかexecutable jar
を実行するように明示するとかすればいいんだけどステップが増えるので今回は回避しています。
-d dependencies=web
はこれがないとウェブアプリケーションにならないので。(webflux
でもいいんだろけど)
-d javaVersion=8
がポイントでherokuのデフォルトJavaバージョンは1.8だったりします。SpringInitializrデフォルトは11なんで、そのままじゃ動かない。
pom.xml
を修正したり、system.properties
(herokuが読む設定)に java.runtime.version=11
とか書いてもいいんだけど、今回は一番ステップが少なくなるの選びました。
普通は system.properties
書くことになると思います。書けばJava16も使えるよ。実際いくつかで使ってたりします。
Applicationクラス作成
コマンドだけで無理やり作るとこう。
% mkdir src/main/java/hoge % cat>src/main/java/hoge/Application.java package hoge; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @SpringBootApplication @RestController public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @RequestMapping String index() { return "hello"; } }
1クラスとはいえIDEで書くのがなんだかんだで早いと思う。importとか書いてられん。
(とはいえIDEで書くと後の git add .
が .
じゃ余計なものが入るので pom.xml
と Application.java
だけaddしなきゃになって若干面倒にはなる。些細な問題だけど。)
@Controller
でなく @RestController
なのはハンドラメソッドの戻りで文字列を直接返したいから。@Controller
だとテンプレート探しに行ってエラーになって /error
なくて404になっちゃう。@ResponseBody
とか書けばいいんだけど面倒だから @RestController
にしちゃった。
あとデフォルトパッケージにすると余計なものコンポーネントスキャンで食っちゃうので、適当でもいいんでパッケージはつけなきゃです。
heroku create
ログインしてないとこれ叩いたときに自動でログイン促されます。ブラウザが開く。
heroku create
は apps:create
の短縮。アプリ名を渡せるけど、指定しなかったら適当につけてくれる。今回はお任せ。
これだと salty-woodland-12925
ですね。(destroy済み)
次の heroku git:remote
は git remote add heroku {herokuのgitのURL}
を代わりにやってくれるコマンドです。git
コマンドを叩いても一緒なんでお好きな方でOK。gitのURLもcreate
時に出てますしね。
ここに push
したらherokuはビルドして動くようにしてくれます。
git push
ソースコードを投げ込むといい感じにビルドしてくれるのがbuildpack。
「pom.xml
があるからMavenだろ」「SpringBootだからこうだろ」みたいなのを雰囲気でやってくれます。
雰囲気でやってくれすぎて何がどうなってるか分からなくなる可能性がそこそこ。
わかりたかったら https://buildpacks.io/ とかで pack
コマンド使って手元でビルドして docker run
とかいじってみると、何かわかるかもしれない。わからないかもしれない。
git push
したらMavenのいつものjarダウンロードのログがダラダラ流れる。git push
でそんなん表示されるのに慣れてないと面食らうかもですね。
成功したらこんな感じ。
Released
とかの次の行の https://... を開いたら動いてる。はず。
今回はherokuのgitにpushしたけど、普段はGitHubからherokuに繋いで使ってます。この辺の連携も素直につながるのでいいですよね。
あとがき
適当にやろうとしたら地味なつまずきかたをしたので整理してみました。 ビルドは3分くらいで終わるんで、スムーズにできれば「ゼロから始めて5分でデプロイ完了」までいけると思います。ドラが鳴る前に終わることを祈る。
今回つまづいたのは
*-plain.jar
のおかげでGradleだと素直に動かない。build.gradle
のjar
タスク止めるか、Procfile
(herokuの設定ファイル)で動かすJar名を明示したらいける。普段は後者でやってる。
- デフォルトJavaバージョンの食い違い
pom.xml
とかbuild.gradle
のバージョン読んでくれるようにきっとそのうちなると信じてる。
……くらいかな? こういうの踏んだときに雰囲気で察しちゃったりするんだけど、「ここにこのログが出てる」と確認しておくのも大事で、そういうのがこの手の素振りの目的だったりもします。
herokuでMaven使った記憶はないんだけど、「どうせいけるだろ」みたいなノリで push
したらいけました。よかったよかった。
この「どうせいけるだろ」みたいな感覚って結構大事だと思ってたりします。たまに大外しするけど。
追記: タイムアタック結果
- start:
2021-08-05T11:20:11
- finish:
2021-08-05T11:22:08
コマンドのみの一発勝負。1分57秒でした。 mkdirから最後にcurlでhelloが返って来るところまで(curlのhello確認は上の手順にないですが。)で、全ログは gist に置いてます。 少し上で「ビルドは3分」とか書いてますが、herokuのご機嫌によりますね。
…… git init
がReinitialized
になってるな。空じゃなかったのか。🤔
似た記事
「ソースコードの公開まで」って感じですね。今回のは手元の動作確認すらしてないという・・・。