この記事はエヌ次元株式会社 Advent Calendar 2022の13日目の記事です。
Django × AWS Elastic Beanstalkを使って個人的にWeb アプリケーションを構築した際に、
Djangoカスタムコマンドの定期実行を実装しようとして、躓いた部分があったので備忘録もかねて投稿させて頂きます。
Djangoカスタムコマンド定期実行の実装
必要なこと
- 定期実行したいDjangoカスタムコマンドの作成
- cron.configの作成
Djangoカスタムコマンドの作成
定期実行したいDjangoカスタムコマンドを作成します。
WebAPIから情報を取ってきて、データベースのデータを更新するという処理を実装しました。(実際のコードからは簡略化してます)
import os
import requests
from django.core.management.base import BaseCommand
from django.utils import timezone
from main.models import Team,Match
from django import setup
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Sampleproject.settings')
setup()
class Command(BaseCommand):
help = 'Update data from webapi'
def handle(self, *args, **options):
leagues = League.objects.all()
league_codes = [league.code for league in leagues]
for league_code in league_codes:
self.update_standing(league_code)
self.update_match(league_code)
def get_dict_from_api(self, url):
# webapiへリクエスト、レスポンスデータの加工など
return data
def update_match(self, league_code):
target_url = 'webapi_url'
input_dict = self.get_dict_from_api(target_url)
for match_info in input_dict['matches']:
# updateしたいオブジェクトをDBからselect
match = Match.objects.get(match_day=match_info['matchday'],
# ...
# 中略(データの更新処理など)
# ...
match.save()
configファイルの設定
.ebextensionsディレクトリ内にconfigファイルを作成します。
ここでは
- 環境変数の設定、Djangoカスタムコマンドを実行するシェルスクリプトの作成
- Cronの設定ファイルの作成
- クリーンアップ
を行っています。
files:
# シェルスクリプトの作成
/usr/local/bin/update_data_script.sh:
mode: "000755"
owner: root
group: root
content: |
#!/bin/bash
source /var/app/venv/staging-LQM1lest/bin/activate
cd /var/app/current
# DB接続情報を環境変数へセッティング
RDS_USERNAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_USERNAME`
export RDS_USERNAME
RDS_PASSWORD=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_PASSWORD`
export RDS_PASSWORD
RDS_HOSTNAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_HOSTNAME`
export RDS_HOSTNAME
RDS_PORT=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_PORT`
export RDS_PORT
RDS_DB_NAME=`/opt/elasticbeanstalk/bin/get-config environment -k RDS_DB_NAME`
export RDS_DB_NAME
# Djangoコマンドの実行
python manage.py update_data
# cronの設定
/etc/cron.d/update_data_cron:
mode: "000644"
owner: root
group: root
# UTC22:30に定時実行(日本時間7:30)
content: |
30 22 * * * root /usr/local/bin/update_data_script.sh
# クリーンアップ
commands:
rm_old_cron:
command: "rm -fr /etc/cron.d/*.bak"
ignoreErrors: true
注意点(躓いたポイント)
RDSへのアクセスが発生するカスタムコマンドを実行する場合、コマンド実行環境の環境変数にRDSへの接続情報を入れておく必要があります。
ElasticBeanstalkではget-configコマンドを使ってRDSの接続情報を取得できるので、それを利用して環境変数に接続情報をsetしています。
自動的に設定してくれるものと勘違いして詰まりました、、、
所感
AWS Elastic BeanstalkはEC2、VPC、RDSなどを自動でセッティングしてくれる便利なサービスですが、拡張的な機能を設定するには、各種configファイルを設定する必要があります。
まだまだ勉強中ですが、公式のドキュメントは充実しているので、うまく活用していければと思います。
参考資料