RenderでScala + PlayなWebアプリを動かす
はじめに
Herokuの無料プランが2022年11月28日で終了する。Herokuの代替サービスとしてRenderがいくつかの記事で紹介された。しかし今のところRenderでScala + Play製のWebアプリケーションを動作させたという記事が(英語含めて)あまり見当たらないため、筆者の運用しているScala + PlayなアプリケーションであるKindle時計サーバーを例に紹介する。
Blueprintの準備
HerokuのようにGUIをポチポチやって環境変数などを登録するやり方とは別に_Blueprint_ というものがある。この記事ではBlueprintを前提とするため、まずはこれを解説する。
Blueprintとは?
Blueprintとはrender.yaml
とDockerfile
をGitHubリポジトリーに設置してRenderに登録することで、Renderがそのリポジトリへのコミットに反応してYAMLの設定を元に自動でアプリをデプロイしておいてくれる仕組みである。上記のKindle時計サーバーはRedisを利用しているが、たとえば他にもデータベースなどミドルウェアに依存している場合はそれらの構成を1つのrender.yaml
で管理することができるため、GUIに比べて便利である。GitHubリポジトリーはprivateでもOKとなっている。
Dockerfile
まずDockerfile
について説明する。自分のアプリケーションでは次のようなDockerfile
を用いている。
# syntax=docker/dockerfile:1
FROM eclipse-temurin:17 as builder
RUN apt-get update && \
apt-get install -y git bash
ENV GIT_BRANCH=master
ADD https://api.github.com/repos/y-yu/kindle-clock/git/refs/heads/$GIT_BRANCH version.json
RUN git clone -b $GIT_BRANCH https://github.com/y-yu/kindle-clock.git && \
cd kindle-clock && \
./sbt "primary/dist"
FROM eclipse-temurin:17-jre-alpine
EXPOSE 80
RUN mkdir /app
COPY /kindle-clock/module/primary/target/universal/primary-0.1.zip /app
RUN apk add --no-cache unzip && \
cd /app && \
unzip ./primary-0.1.zip && \
apk del unzip
RUN apk add --no-cache bash
WORKDIR /app/primary-0.1
CMD ./bin/primary -Dhttp.port=80
前半がGitHubからKindle時計をgit clone
してきてsbt dist
でビルドする部分であり、後半はサーバーを起動させるメインのDockerイメージを構成する部分である。Renderのドキュメントにはっきりとそう書いてあるわけではないが、いろいろ試したところ次のような部分が重要と考えられる。
-
EXPOSE
でポートを指定すればそこでリッスンできるらしい- ただし特定のポートをリッスンすることができない
-
ENTRYPOINT
ではなくCMD
でサーバーを起動しないとデプロイ失敗になる- これは筆者がDockerをよくわかっていないことに起因していると思われる……😇
- RenderのDockerビルドにはキャッシュが効く。しかし
y-yu/kindle-server.git
に更新があればキャッシュを使わないでほしいので、StackOverflowを参考にしてこのようにADD
でversion.json
を出力させることでGitHubリポジトリーに差分があればキャッシュを使わないようにしている
render.yaml
次は先ほどつくったDockerfile
を使って全体のサービスを構成するための設定であるrender.yaml
を執筆する。Kindle時計サーバーはRedisに依存するので次のようになる。
services:
- type: web
name: kindle-clock
env: docker
dockerfilePath: Dockerfile
plan: free
numInstances: 1
envVars:
- key: JAVA_OPTS
value: -Xmx400m -XX:+UseSerialGC -Xlog:gc*=info:stdout:time,uptime,level,tags
- key: OPEN_WEATHER_MAP_APP_ID
value: *********
- key: OPEN_WEATHER_MAP_ID
value: *********
- key: APPLICATION_SECRET
value: *********
- key: AUTH_TOKEN
value: *********
- key: AWAIR_OAUTH_TOKEN
value: *********
- key: NATURE_REMO_OAUTH_TOKEN
value: *********
- key: SWITCHBOT_OAUTH_TOKEN
value: *********
- key: REDIS_URL
fromService:
name: redis-kindle-clock
type: redis
property: connectionString
- type: redis
name: redis-kindle-clock
plan: free
maxmemoryPolicy: allkeys-lru
ipAllowList: []
このようにRedisなどのサービスを1つのYAML設定に押し込むことができて便利である。あまり注意することはないが次のようなことがある。
-
Herokuからのマイグレーションを行った場合、Redisのプランが有料である
plan: starter
になっているので、無料で使う場合はfree
にしておく必要がある
これらが終わったらこの2つのファイルをGitHubのリポジトリにgit push
すればOKとなる。
Blueprintの作成
https://dashboard.render.com/blueprintsからNew Blueprint Instance
ボタンを押すと下記の画像のような画面になる。
あとはここから先ほど作成したGitHubリポジトリーを選択すればOKとなる。あとはgit push
するたびに自動でデプロイなどが実行される。
自動デプロイ
RenderにはデプロイをKickするためのURLが用意されているので、これをGitHub Actionsで叩けばよい。
このURLをGitHubのシークレットにたとえばRENDER_DEPLOY_URL
などと登録しておき、下記のようなGitHub Actionsを登録すればOKとなる。
name: Deploy to Render
on:
workflow_dispatch:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy Render
run: curl -sSfL ${{ secrets.RENDER_DEPLOY_URL }}
まとめ
Scala + Play製のアプリケーションをRenderで動かす方法について解説した。Herokuの無料プランが終わってしまって引っ越し先を検討している方の参考になればいいと思う。
Discussion