DjangoアプリをRenderにデプロイ

概要

DjangoアプリをRenderにデプロイしました。

きっかけ

習作のDjangoアプリの置き場として無料で利用できるHerokuを利用させて貰っていましたが、2022年11月28日から無料のサービスの停止するとのこと。
移行先としてRenderを選択し、既存のDjangoアプリをRenderにデプロイしました。

RenderにDjangoアプリをデプロイ

やることはDjangoアプリをRender用に修正することと、Renderにデプロイする作業の二つです。

Djangoアプリの修正

RenderにデプロイするためにDjangoアプリのsettings.pyを修正します。

# settings when deployed to render.com
if 'RENDER' in os.environ:
    import dj_database_url

    # set DEBUG to false
    DEBUG = False

    # get the secret key from env vars.
    SECRET_KEY = os.environ['SECRET_KEY']

    # add the hostname to ALLOWED_HOSTS.
    RENDER_EXTERNAL_HOSTNAME = os.environ.get('RENDER_EXTERNAL_HOSTNAME')
    if RENDER_EXTERNAL_HOSTNAME:
        ALLOWED_HOSTS.append(RENDER_EXTERNAL_HOSTNAME)

    # set postgreSQL database.
    DATABASES['default'] = dj_database_url.config(
        default='postgres://ユーザ名:パスワード@localhost:5432/データベース名',  # postgres://USER:PASSWORD@HOST:PORT/NAME
        conn_max_age=600
    )

    # add WhiteNoise to middleware.
    WHITE_NOISE = 'whitenoise.middleware.WhiteNoiseMiddleware'
    if WHITE_NOISE not in MIDDLEWARE:
        MIDDLEWARE.append(WHITE_NOISE)

    STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

これをsettings.pyの末尾の方に貼り付けます。

内容は、SECRET_KEY環境変数から取得、ドメイン名も環境変数から取得してALLOWED_HOSTSに追加、データベースとしてpostgresを設定、WhiteNoiseの設定です。Herokuのときと同じです。
Render上で動かしてるときは環境変数RENDERが定義されているので、if文でRender用の設定をするようにしています。

render.yamlを用意

Renderにデプロイする方法は大きく二つあり、一つはダッシュボードから新しいウェブサービスやデータベースを作成する方法、もう一つはRenderのサービスの設定を記載したrender.yamlをアプリのリポジトリのルートディレクトリに置いて新しいBlueprintを開始する方法です。

今回はrender.yamlを作成する方法を利用します。

services:
  - name: アプリ名
    type: web
    env: python
    repo: リポジトリ
    branch: main
    plan: free
    region: singapore
    buildCommand: pip3 install -r requirements.txt && python manage.py collectstatic --no-input && python manage.py migrate
    startCommand: gunicorn アプリ名.wsgi:application
    envVars:
      - key: SECRET_KEY
        generateValue: true
      - key: PYTHON_VERSION
        value: 3.10.7
      - key: DATABASE_URL
        fromDatabase:
          name: データベース名
          property: connectionString

databases:
  - name: データベース名
    plan: free
    region: singapore

基本はこんな感じです。 各行を見ていきます。
servicesの項目はRenderのサービスの設定を定義していきます。
nameDjangoアプリのアプリ名を入力します。
typeは作るウェブサービスの種類です。Webサービスweb
envはRenderの環境の指定。Pythonを使いたいのでpython
repoはアプリのリポジトリのURLを指定。github上のリポジトリなら"https://github.com/アカウント名/リポジトリ名.git"。
branchリポジトリのブランチを指定します。mainに設定。(記事執筆時のdocsにはデフォルトではmasterになると書いてあります。)
planは料金プラン。freeを設定。
regionはサービスをホストする地域。必須の項目ではないですが、日本に近いsingaporeを選択。参考: https://render.com/docs/regions
buildCommandはアプリをビルドするときに実行するコマンドです。ここではライブラリのインストール、静的ファイルの配置、アプリのマイグレーションを実行。ガイドページなどでは、スクリプトを別ファイルとして作成しリポジトリに置き、それを実行する形にしています。
startCommandはアプリを起動するときに実行するコマンドです。HerokuのProcfileに対応します。buildCommandと同じく、複雑ならスクリプトにするのが良し。
envVars環境変数の定義です。必要な変数を辞書形式で追加していきます。
SECRET_KEYgenerateValuetrueに設定して、settings.pyで利用する環境変数SECRET_KEYをRenderの環境で自動生成しています。
PYTHON_VERSIONpythonのバージョンを指定します。記載しなかった場合のデフォルトはdocsによると、記事執筆時では3.7のようです。
DATABASE_URLではデータベースを指定します。IPアドレス指定によるアクセス制限もできるようですが、今回はなし。
databasesを追加することでデータベースを利用できます。 無料プランだと利用出来るデータベースは制限があります。参考: https://render.com/docs/free
使えるデータベースサーバがpostgresのみであること、作成後90日で停止されることなどです。 本格的なサービス運用には向いてないですが、学習用と考えれば利用できるだけでとてもありがたいです。
databasesの方もplanregionを設定しておきます。

なお、私のアプリが動くようにしているだけで、アプリに応じて修正が必要なはずです(buildCommandstartCommandenvVarsに追加する環境変数databasesの項目など)。render.yamlの書き方の詳細はドキュメント参照。

Blueprint ページから立ち上げ

ダッシュボードNew Blueprintを選択。
GitHubアカウントかGitLabアカウントをrenderに紐づけするか、Publicなリポジトリを指定するかします。リポジトリを指定してApplyをクリックします。

Service Group Name にサービス名称、Branch にブランチ名を入力してApplyボタンを押すとデプロイが開始されます。

デプロイ確認

ダッシュボードからデプロイの状況を見ることが出来ます。 デプロイにかかる時間はHerokuに比べて長いです。

ダッシュボードのBlueprintsのタブからさっき作成したサービスの状態がSync succeed、ダッシュボードのDashboardタブの作成したウェブサービスやデータベースの状態がDeploy succeedやAvailableなどとなっていたら成功です。
ウェブサービスをクリックするとサービスのデプロイの履歴から、各デプロイのログを参照できるので、デプロイに失敗したときはここからエラーメッセージを見ることができます。

作成したウェブページはドメイン名を変更していないならば"https://ウェブサービス名.onrender.com"でアクセス出来るようです。

出来たページ: https://kj-apps.onrender.com
アクセスしてみると…結構遅いですね。無料プランでは15分アクセスが無いとサスペンドするため、15分間置いてアクセスする場合はその都度サービスを開始しているのですが、立ち上げにかかる時間もHerokuのときより長い気がします。

おわりに

DjangoアプリをRenderにデプロイしました。
このようなサービスを無料で提供して頂いてることは非常にありがたいです。

参考