Elastic Beanstalk 環境にDjangoアプリの管理者ユーザーを作成する
概要
Django(REST framework) + PostgreSQLのアプリケーションをElastic Beanstalk環境にデプロイしたものの、管理画面にアクセスできない...というか管理者アカウント生成で詰まったのでその備忘録に。
ローカル環境では python manage.py createsuperuser
で管理者ユーザーを生成できる。
が、そのあとでデプロイするだけだと管理画面にアクセスはできても、ログインができない。
結論、重要な点だけ抜き出すと下記のファイルをイジる必要がある
- ./.ebextensions/django.config
- ./{myapp}/management/commands/createsu.py
- ./{config}/settings.py
※ {myapp} と {config} は任意のディレクトリ名。
※ {myapp} は views.py
や models.py
が格納されているディレクトリ
※ {config} は asgi.py
や wsgi.py
が格納されているディレクトリ
前提:psycopg2-binary
この構成でPostgreSQLを扱う際、pipモジュールのpostgresではなくpsycopg2-binaryを使用しなければいけないので注意。
requirements.txt
にも psycopg2-binary
だけを記述する。もしpostgresをpipインストールしてしまっている場合は削除する。
1: ./.ebextensions/django.config
Elastic Beanstalk環境にデプロイする際、サーバー側で実行されるコマンド群を記すファイル。
これの container_commands
オプションを下記のようにする。
container_commands:
01_makeMigrations:
command: "source /var/app/venv/*/bin/activate && python3 manage.py makemigrations --noinput"
leader_only: true
02_migrate:
command: "source /var/app/venv/*/bin/activate && python3 manage.py migrate --noinput"
leader_only: true
03_createsu:
command: "source /var/app/venv/*/bin/activate && python3 manage.py createsu"
04_collectstatic:
command: "source /var/app/venv/*/bin/activate && python3 manage.py collectstatic --noinput"
leader_only: true
これらのコマンドはデプロイ時に上から順に実行される。
03_createsu には、後述する createsu.py
ファイルを実行するよう命令が書かれている。
2: ./{myapp}/management/commands/createsu.py
下記を丸ごとコピペでOK。
{username} などと表記している部分に関しては、 python manage.py createsuperuser
で作成した任意のユーザー情報に置き換える。
※ この記事では割愛するが、セキュリティの面からこれらの情報は .env
ファイルなどにまとめて外に公開しないよう気をつけるのがベター。
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth import get_user_model
User = get_user_model()
class Command(BaseCommand):
def handle(self, *args, **options):
if not User.objects.filter(username={username}).exists():
User.objects.create_superuser(
username={username},
email={email},
password={password})
self.stdout.write(self.style.SUCCESS('Successfully created new super user'))
また、このファイルはモジュール化させないとなので management
, commands
ディレクトリそれぞれに __init__.py
を配置する。(中身は空でOK)
↓このようなイメージ。
なお、こちらの部分に関してはこの記事を参考にさせてもらいました。
3: ./{config}/settings.py
このファイルによりサーバー上でDjangoアプリとデータベースを接続する。
import os
from dotenv import load_dotenv
load_dotenv()
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': os.environ['RDS_DB_NAME'],
'USER': os.environ['RDS_USERNAME'],
'PASSWORD': os.environ['RDS_PASSWORD'],
'HOST': os.environ['RDS_HOSTNAME'],
'PORT': os.environ['RDS_PORT'],
}
}
こちらは公式のコードのコピペ + python-dotenvをインポートしている。
これをしないと os.environ['xxx']
の部分で読み込みできないケースがある(たぶん。少なくともローカル環境ではそう)。
設定が終わったら...
あとは eb deploy
すればOK。
ログイン画面 http://{myapp}/admin
にて、設定したIDとパスワードでログインできるはず。
Discussion