LoginSignup
10
8

More than 1 year has passed since last update.

Renderにデプロイ(Django)

Last updated at Posted at 2022-12-10

Herokuの無料枠が無くなったので、デプロイ環境をRenderに移す

  • まずは、以下のレポジトリからソースをダウンロードする。
  • これをもとにRenderへのデプロイ方法を紹介していく。

  • ダウンロードファイルを開いて、その場で以下のコマンドを実行する(仮想環境作成)
  • 本記事では、仮想環境名をmyenvにしている。
mac専用
$ python3 -m venv 仮想環境名
$ source 仮想環境名/bin/activate

※以下の記事で、アプリの作成方法を説明している。

デプロイの流れ要点

  • デプロイ前準備
    • 既存ファイルの削除
    • 既存ファイルの修正
    • 新規ファイル作成(Renderデプロイ用)
    • Djangoのカスタムコマンドを作る
  • GitHubにコミットする
  • RenderとGitHubを連携する
  • Renderにデプロイ

Renderについて

RenderはHerokuと同様、PaaS型のクラウドプラットフォーム。
RDBMSも両者PostgreSQLになっている。
また、次の記事「【格安本番運用が可能に】Render.com のメリット・デメリットを Heroku と比較してみた」では、Herokuとの違いやデプロイ時の詳細設定について解説している。

個人的に、RenderはHerokuを意識している印象。

デプロイ前準備

既存ファイルの削除

以下の既存ファイルを削除する。

  • Procfile(Heroku専用)
  • runtime.txt(Heroku専用)
  • report_project/settings_local.py
  • README.md(pushに時間がかかってしまうので)

既存ファイルの修正

以下の既存ファイルを修正する。

  • requirements.txt
  • settings.py
  • .env

requirements.txt

requirements.txt
asgiref==3.5.2
dj-database-url==1.0.0
dj-static==0.0.6
Django==4.1.2
django-environ==0.9.0
django-model-utils==4.2.0
gunicorn==20.1.0
psycopg2-binary==2.9.5
python-decouple==3.6
python-dotenv==0.21.0
sqlparse==0.4.3
static3==0.7.0
whitenoise==6.2.0

ローカル環境で動作確認を行う場合は、以下のコマンドを実行して、仮想環境上(ここでは、myenv)にライブラリをインストールする。

※仮想環境の作成方法:仮想環境の作成とactivate

(myenv) $ pip install -r requirements.txt

settings.py

  • 以下、4点の修正を加える
    • ALLOWED_HOSTS
    • DB設定
    • staticファイル
    • .envファイルからの環境変数読み込み
    • Herokuの設定を解除
settings.py
ALLOWED_HOSTS = ['127.0.0.1', 'daily-report.onrender.com']

デプロイ完了後のアプリのURLを指定する。つまり、daily-report.onrender.comのところを独自のアプリケーションURLにする。

settings.py(修正前)
DATABASES = {
    'default': {
        'ENGINE':'django.db.backends.postgresql_psycopg2', # PostgreSQL使いますよ宣言
        'NAME': 'appdb', # データベース名
        'USER': 'postgres', # データベースに接続するDBユーザー名
        'PASSWORD': 'password1', # データベースに接続する際のDBユーザのパスワード
        'HOST': '', # 'localhost'
        'PORT': '', # 5432
    }
}

既存のものを以下に変更する。

setting.py
import dj_database_url
# ~省略~
default_dburl = "sqlite:///" + str(BASE_DIR / "db.sqlite3")
DATABASES = {'default': dj_database_url.config(default=default_dburl)}
# postgresqlを設定する場合の書式は、postgresql://user_name:password@localhost:port/database_name(以下では、既存のものを書籍に当てはめている)
# DATABASES = {'default': dj_database_url.parse('postgresql://postgres:password1@localhost:5432/appdb')}

この設定にすると、データベースの設定は、「DATABASE_URL」という環境変数から読み込むようになります。これで、環境変数の指定を外部から変更できるようになります。
また、環境変数の指定がない場合には、Django の標準設定である、「SQLite」を利用します。
※Renderにデプロイすると自動的に、「DATABASE_URL」の値が設定される。

settings.py
STATIC_URL = 'static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# 以下を追加
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

STATIC_ROOT環境変数の下に追加

作成したnewsuperuserコマンド実行時に、settings.pyから値を取得するように定義したので、以下を追加する。

settings.py
dotenv.load_dotenv() # .env ファイルを読み込む
SECRET_KEY = os.getenv('SECREST_KEY') # .env内の環境変数を取得
SUPERUSER_NAME = os.getenv('SUPERUSER_NAME')
SUPERUSER_EMAIL = os.getenv('SUPERUSER_EMAIL')
SUPERUSER_PASSWORD = os.getenv('SUPERUSER_PASSWORD')

末尾のHerokuに関する設定をコメントアウト、または削除する。

settings.py
DEBUG = False # デプロイ時、Falseに修正
#DEBUG = True
#if not DEBUG:
    #import django_heroku
    #django_heroku.settings(locals())

新規ファイル作成(Renderデプロイ用)

  • .env(環境変数設定用)
  • build.sh
  • render.yaml
  • report/management/commands/newsuperuser.py(Renderの無料枠を使うため)

以下では、Render公式の「Getting Started with Django on Render」に記載されているものを参考にしていく。

.env

公に公開したくない環境変数をこのファイルに記述していく。
(.envは、.gitignoreに記述されているのでGitHub上で管理されない)

.env
SUPERUSER_NAME = admin
SUPERUSER_EMAIL = admin@admin.com
SUPERUSER_PASSWORD = password
SECREST_KEY = ~~以下の説明をもとに値を設定する~~
  • ここでは、今回のサービスのDjangoスーパーユーザーに関する設定と重要なSECREST_KEYの設定を記述している。
  • これらの値は、settings.pyより取得される
  • 末尾のSECREST_KEYの値の生成と設定方法は、「SECRET_KEY(環境変数)とは」を確認すること。

※SUPERUSER_EMAILは、#を先頭につけてコメントアウトしても問題ない

build.sh

デプロイ環境上で(ビルド時)実行するコマンドを記述する。

build.sh
#!/usr/bin/env bash
# exit on error
set -o errexit

pip install -r requirements.txt

python manage.py collectstatic --no-input
python manage.py migrate
python manage.py newsuperuser
  • pip install -r requirements.txt:デプロイ環境にライブラリをインストールするため。
  • python manage.py collectstatic --no-input:--no-inputとしているのは、staticファイルをコレクト時にyesを入力することを省略するため。
  • python manage.py migrate:モデルをDB上に反映させるため。
  • python manage.py newsuperuser:後の**「Djangoのカスタムコマンドを作る」**の説明のところで作成するカスタムコマンド。

render.yaml

デプロイ環境の設定を記述する。

render.yaml
databases:
  - name: mysite
    databaseName: mysite
    user: mysite
    region: singapore
    plan: free

services:
  - type: web
    name: mysite
    env: python
    region: singapore
    plan: free
    branch: main
    healthCheckPath: /
    buildCommand: "./build.sh"
    startCommand: "gunicorn report_project.wsgi --log-file -"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: mysite
          property: connectionString
      - key: SECRET_KEY
        generateValue: true
      - key: WEB_CONCURRENCY
        value: 4


    autoDeploy: true
  • databases:DBの設定
    • name:Render上で表示するDB名
    • databaseName:DB名
    • user:DBユーザー名
    • region:DBサーバーの地域
    • plan:DBのプラン
  • services:サービスの設定
    • name:サービス名(URLになる)
    • env:開発言語
    • startCommand:APサーバー(gunicorn)を起動コマンド「gunicorn 自分のプロジェクト設定dir名.wsgi」
    • envVars:環境変数の設定

envVarsの設定値以外は、小文字でないといけないかも

Djangoのカスタムコマンドを作る

Renderの無料枠では、 「Render側のシェル機能を使用することができない」
そのため、Djangoのスーパーユーザー(管理ユーザー)を事前に作成するためのコマンドを定義しておく必要がある。
以下では、「Djangoのカスタムコマンドを作成してコマンドラインから実行する」の記事を参考に、要点を説明していく。

「build.sh」の説明のところで、末尾に記述しているpython manage.py newsuperuserコマンドを作成していく

要点 説明
python manage.py コマンド名を実行した時に処理する独自のコマンドを作成する。(今回はpython manage.py newsuperuserコマンド)
ディレクトリは、アプリ/management/commands/直下にコマンド名となるpythonファイルを作成する(今回はreport/management/commands/newsuperuser.py)
BaseCommandクラスを継承してカスタムコマンドを作成する
コマンド実行後の処理は、handle()メソッド内に定義する
report/management/commands/newsuperuser.py
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.conf import settings

CustomUser = get_user_model()


class Command(BaseCommand):
    def handle(self, *args, **options):
        if not CustomUser.objects.filter(username=settings.SUPERUSER_NAME).exists():
            CustomUser.objects.create_superuser(
                username=settings.SUPERUSER_NAME,
                email=settings.SUPERUSER_EMAIL,
                password=settings.SUPERUSER_PASSWORD
            )
            print("スーパーユーザー作成に成功しました")
  • CustomUser = get_user_model():カスタムユーザーモデルを読み込む
  • CustomUser.objects.create_superuser():カスタムユーザーモデルのマネージャーメソッドcreate_superuser()。引数に、スーパーユーザー名, スーパーユーザーemail, スーパーユーザーpasswordを指定する。

※厳密には、create_superuser()は、カスタムユーザーモデルが継承しているUserManagerクラスのメソッド(objects = UserManager())

参考記事:【Django】独自ユーザーモデルの作成(カスタムUserモデル:AbstractBaseUser)

GitHubにpushする

以下の記事を参考に、リポジトリに登録してpushする。
参考記事:レポジトリに登録してpush
参考記事:一旦pushしたい場合

RenderとGitHubを連携する

  • Renderの公式ページにアクセスする。

  • 右上の「DASHBOARD」をクリックする
    スクリーンショット 2022-12-09 14.42.55.png

  • 「GitHub」をクリックし、連携が完了する
    スクリーンショット 2022-12-09 14.46.34.png

Renderにデプロイ

  • ナビゲーションバーの「Blueprints」をクリック
  • 「New Blueprint Instance」をクリック
  • GitHubのレポジトリ一覧が表示される
    • デプロイしたいものの「Connect」をクリック
  • 「Service Group Name」にrender.yamlのservicesのnameの値を入力する
  • 「Apply」をクリック(デプロイ開始)

※これだけでは、Render側で環境変数を設定していないのでデプロイに失敗する。最後に以下の手順を踏む。

Render側(デプロイ環境)の環境変数の値を設定する

  • Render公式ページのナビゲーションバー「Dashboard」をクリック
  • 先ほどデプロイしたサービスが表示されていることがわかる
  • デプロイしたサービス名(DBではなく)をクリック
  • 「Environment」をクリック
  • PYTHON_VERSION, SECREST_KEY, SUPERUSER_NAME, SUPERUSER_PASSWORDを追加し、ローカルのpythonのバージョンと.envに記載した値を入力して「Save Changes」をクリック
  • 右上の「Manual Deploy」をクリックし、「Deploy latest commit」をクリック(再度デプロイ)

スクリーンショット 2022-12-09 15.02.09.png

  • PYTHON_VEWSIONには3.7以上を指定する必要がある。(Django==4.1.2を使用するため。)今回は、3.10.7を指定している。
  • あとは、.envで指定した値を設定する。

※Renderの無料枠を使用しているので、デプロイに時間がかかるが焦らずに待機する。

まとめ

以上が、DjangoをRenderへデプロイする方法でした。
ついつい最後のRender側の環境変数を設定し忘れてしまい、デプロイに失敗していましたが解決できてよかったです。
また、無料枠なので、デプロイに時間がかかりましたが問題なくサービスが稼働していることが確認できました。
わかりづらい点もあったかと思いますが、最後までお付き合いいただきありがとうございました。

Appendix

動作確認(ローカル)

ローカルで動作確認を行う場合は、以下のコマンドを実行するように。

$ python manage.py makemigrations
$ python manage.py migrate
$ python manage.py runserver
10
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
8