Upgrade to Pro — share decks privately, control downloads, hide ads and more …

本番運用を想定したDjango settings.pyの書き方入門

本番運用を想定したDjango settings.pyの書き方入門

Open Source Conference 2021 Online Nagoya資料
https://event.ospn.jp/osc2021-online-nagoya/session/312812

C5b4d57a23b991d41ac0a89926ab4f8a?s=128

Ryuji Tsutsui

May 29, 2021
Tweet

Transcript

  1. ຊ൪ӡ༻Λ૝ఆͨ͠ Django settings.pyͷॻ͖ ํೖ໳ Ryuji Tsutsui Open Source Conference 2021

    Online Nagoyaࢿྉ 2021/05/29
  2. ࣗݾ঺հ • Ryuji Tsutsui@ryu22e • Ұൠࣾஂ๏ਓPyCon JP Association͔Βདྷ·ͨ͠ • ීஈ͸࿡ຊ໦ͷϑΟϯςοΫܥاۀͰDjangoΛ࢖ͬͯWebαʔϏε

    Λ࡞͍ͬͯ·͢ • Djangoྺ͸8೥͙Β͍ • Python Boot CampίΞελοϑͱͯ͠׆ಈ͍ͯ͠·͢
  3. ࠓ೔࿩͢͜ͱ • ຊ൪؀ڥͰ࢖͑ΔDjangoΞϓϦέʔγϣϯͷઃܭʹ͍ͭͯɺ
 Έͳ͞Μͱϊ΢ϋ΢Λز͔ͭڞ༗͠·͢ • ࠓճ͸settings.pyʢDjangoͷઃఆϑΝΠϧʣͷॻ͖ํʹ͍ͭͯ࿩͠ ·͢

  4. ओʹ3఺ʹ͍ͭͯ࿩͠·͢ • 1. ֤؀ڥ༻ͷઃఆ • 2. ൿີͷ஋ͷॻ͖ํ • 3. ϩάઃఆ

  5. ͜Μͳਓ޲͚ͷηογϣϯͰ͢ • ʮDjangoͷνϡʔτϦΞϧ͙Β͍͸΍ͬͨ͜ͱ͕͋Δ͚Ͳຊ൪؀ڥ Ͱಈ͔͢ΞϓϦέʔγϣϯΛ࡞ͬͨ͜ͱ͸ͳ͍ʯͱ͍͏ਓ޲͚Ͱ͢

  6. ʢ·ͣ͸͓͞Β͍ʣ
 settings.pyͬͯԿ͚ͩͬʁ

  7. settings.pyͱ͸ʁ $ django-admin startproject django_example $ cd django_example $ tree

    django_example django_example !"" __init__.py !"" asgi.py !"" settings.py !"" urls.py #"" wsgi.py %KBOHPϓϩδΣΫτશମͰࢀরͰ͖Δάϩʔόϧͳ ఆ਺ΛఆٛͰ͖Δ
  8. settings.pyͷॻ͖ํ DEBUG = True LANGUAGE_CODE = 'ja' TIME_ZONE = 'UTC'

    ී௨ʹ1ZUIPOͷఆ਺Λॻ͚ͩ͘
  9. settings.pyʹॻ͍ͨઃఆΛݺͼग़͢ํ๏ >>> from django.conf import settings >>> settings.DEBUG True >>>

    settings.LANGUAGE_CODE 'ja' EKBOHPDPOGTFUUJOHTΛܦ༝ͯ͠ݺͼ·͢
  10. 1. ֤؀ڥ༻ͷઃఆ

  11. ͜Μͳ࣌Ͳ͏͢Ε͹͍͍ͷͩΖ͏…ʁ INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',

    'debug_toolbar', # ։ൃ؀ڥ͔͠࢖Θͳ͍ઃఆ ] ALLOWED_HOSTS = [ 'example.com', # ຊ൪؀ڥ͔͠࢖Θͳ͍ઃఆ ] ։ൃ؀ڥɾຊ൪؀ڥͲͪΒʹͱͬͯ΋ෆཁͳઃఆ ؚ͕·Ε͍ͯΔʜ
  12. ΞϓϦىಈલʹෆཁͳߦΛίϝϯτΞ΢τ͢Δʁ INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',

    # 'debug_toolbar', # ։ൃ؀ڥ͔͠࢖Θͳ͍ઃఆ ] ALLOWED_HOSTS = [ 'example.com', # ຊ൪؀ڥ͔͠࢖Θͳ͍ઃఆ ] ϛε͕͋Γͦ͏ͳͷͰ΍Γͨ͘ͳ͍
  13. ༗ޮແޮΛ੾Γସ͑ΔΦϓγϣϯΛ༻ҙ͢Δʁ MODE = ... # ؀ڥม਺͔MODEΛఆٛͨ͠ผͷϑΝΠϧΛಡΈࠐΉ INSTALLED_APPS = [ 'django.contrib.admin',

    'django.contrib.auth', # ʢলུʣ ] if MODE == 'local': INSTALLED_APPS += ['debug_toolbar'] ίϝϯτΞ΢τΑΓ͸ΦϖϛεͷՄ ೳੑ͸௿ͦ͏͚ͩͲʜ
  14. ༗ޮແޮΛ੾Γସ͑ΔΦϓγϣϯΛ༻ҙ͢Δʁ if MODE == 'local': INSTALLED_APPS.append('debug_toolbar') if MODE == 'production':

    ALLOWED_HOSTS = ['example.com'] elif MODE == 'staging': ALLOWED_HOSTS = ['staging.example.com'] else: ALLOWED_HOSTS = ['*'] if MODE == 'staging': ... Φϓγϣϯ͕૿͑Δͱઃఆ͕ෳࡶԽ ͦ͠͏
  15. ͜Μͳ࣌͸ઃఆϑΝΠϧΛ؀ڥ͝ͱʹ෼͚· ͠ΐ͏

  16. ͜ͷΑ͏ͳߏ੒͕͓קΊ django_example #"" settings # settings.py͕͋ͬͨ৔ॴʹ͜ΕΛ࡞Δ !"" __init__.py !"" base.py

    # ͢΂ͯͷ؀ڥͰ࢖͏ڞ௨ͷઃఆ !"" local.py # ։ൃ؀ڥ༻ͷઃఆ !"" production.py # ຊ൪؀ڥ༻ͷઃఆ #"" staging.py # εςʔδϯά؀ڥ༻ͷઃఆ TFUUJOHTQZ͸ফ͢
  17. ֤ϑΝΠϧͷ಺༰ INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', # ʢলུʣ ] ROOT_URLCONF

    = 'django_example.urls' WSGI_APPLICATION = 'django_example.wsgi.application' base.pyʢڞ௨ͷઃఆʣ
  18. from .base import * DEBUG = False ALLOWED_HOSTS = [

    'staging.example.com', ] ֤ϑΝΠϧͷ಺༰ from .base import * DEBUG = False ALLOWED_HOSTS = [ 'example.com', ] from .base import * DEBUG = True INSTALLED_APPS += ['debug_toolbar'] stagings.pyʢεςʔδϯά؀ڥ༻ʣ local.pyʢ։ൃ؀ڥ༻ʣ production.pyʢຊ൪؀ڥ༻ʣ ͜͜Ͱڞ௨ͷઃఆ ΛಡΈࠐΉ
  19. Ͳ͏΍ͬͯ࢖͏ઃఆϑΝΠϧΛ੾Γସ͑Δ͔ • ؀ڥม਺DJANGO_SETTINGS_MODULEΛ࢖͍·͠ΐ͏ • ྫ͑͹ɺຊ൪؀ڥͳΒ͜͏͠·͢ • DJANGO_SETTINGS_MODULE="django_example.settings.production" • ϑΝΠϧύεͰ͸ͳͯ͘Pythonͷimportจʹॻ͘ͱ͖ͷυοτͰܨ͛ͨॻ͖ ํͰ͋Δ͜ͱʹ஫ҙ͍ͯͩ͘͠͞

    • Ұ࣌తʹ࢖͏ઃఆϑΝΠϧΛ੾Γସ͍͑ͨͳΒɺDjangoίϚϯυʹ--settings ΦϓγϣϯΛࢦఆ͠·͢
  20. ؀ڥม਺ΛͲ͜ʹઃఆ͢Ε͹͍͍͔ʁ • ࢖͍ͬͯΔϓϥοτϑΥʔϜʢΦϯϓϨ or Ϋϥ΢υʣʹΑͬͯҧ͏ ͷͰɺҰ֓ʹ͜Εɺͱ͍͏ͷ͸ݴ͑·ͤΜ͕ɺز͔ͭྫΛڍ͛·͢

  21. ؀ڥม਺ͷઃఆํ๏ྫ • .bashrcʹʮexport DJANGO_SETTINGS_MODULE="..."ʯΛॻ͍͓ͯ ͘ • systemdͷEnvironmentFileΛར༻͢Δ • AWS Systems

    Manager ύϥϝʔλετΞΛར༻͢Δ • Google Cloud Secret ManagerΛར༻͢Δ
  22. manage.pyͷฤू͕ඞཁ #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import

    os import sys def main(): """Run administrative tasks.""" os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_example.settings') # ʢলུʣ ͜͜ΛʮEKBOHP@FYBNQMFTFUUJOHTMPDBMʯʹมߋ
  23. 2. ൿີͷ஋ͷॻ͖ํ

  24. ͜ΜͳઃఆΛॻ͍ͯ͸͍͚ͳ͍ʂ

  25. ͪͳΈʹGitHubͰࠓͷίʔυΛެ։͢Δͱ͜Μͳϝʔϧ͕ಧ͖·͢

  26. ൿີͷ஋͸؀ڥม਺͔ΒಡΈऔΔΑ͏ʹ import os AWS_ACCESS_KEY_ID = os.environ.get( "DJANGO_AWS_ACCESS_KEY_ID" ) ͨͩɺ͜ͷॻ͖ํͩͱ؀ڥม਺ͷઃఆ࿙Εͷࡍʹ /POF͕ೖͬͯ͠·͏ͷͰɺ΋͏ͻͱ޻෉ඞཁ

  27. ඞਢͷ؀ڥม਺͸Ͳ͏΍ͬͯॻ͘ʁ import os from django.core.exception import ImproperlyConfigured # os.environʹ֘౰͢Δ஋͕ͳ͚Ε͹ྫ֎Λૹग़͢Δؔ਺Λ࡞Δ def

    get_env_variable(var_name): try: os.environ[var_name] except KeyError: # os.environʹ֘౰͢ΔΩʔ͕ͳ͍৔߹ʹԿͷΩʔ͕଍Γͳ͍͔Λྫ֎ϝοηʔδʹؚΉ error_msg = "Set the {} environment variable".format(var_name) raise ImproperlyConfigured(error_msg) Ҿ༻ݩʮ5XP4DPPQTPG%KBOHPYʯ ϖʔδ
  28. ͜ΜͳϥΠϒϥϦ΋͓קΊ • django-environ • PyPI: https://pypi.org/project/django-environ/ • EnvΫϥεܦ༝Ͱ؀ڥม਺Λݺͼग़͢ͱɺઃఆ࿙ΕΛݕग़Ͱ͖· ͢ɻ •

    bool, intͳͲܕม׵΋΍ͬͯ͘Ε·͢ɻ
  29. 3. ϩάઃఆ

  30. Djangoͷϩάઃఆͷ΍Γํ • LOGGINGͱ͍͏߲໨ʹࣙॻܕͰઃఆΛॻ͖·͢ • ʢͬ͘͟Γઆ໌͢ΔͱʣϩάΛͲ͜ʹग़ྗ͢Δ͔Λ͜͜ͰܾΊ·͢ • ग़ྗઌͷྫ • ϝʔϧ •

    ඪ४ग़ྗ • ϩʔΧϧϑΝΠϧ • ϩάϩʔςʔγϣϯʢݹ͍ϩάͷΞʔΧΠϒ΍࡟আʣ΋Ͱ͖·͢ • ʮϩάϨϕϧʯʢDEBUG, INFO, WARNING, ERROR, CRITICALʣ΍ϩάग़ྗݩͷϞδϡʔϧʹ Αͬͯग़ྗઌΛ੾Γସ͑Δ͜ͱ΋Ͱ͖·͢
  31. LOGGINGͷઃఆ্͸ɺग़ྗઌ͸ඪ४ग़ྗͷΈʹ ͢Δ • LOGGING্Ͱͷग़ྗઌ͸͢΂ͯඪ४ग़ྗ • ඪ४ग़ྗͷϩάΛͲ͏ѻ͏͔͸ɺΞϓϦͷ֎ʹ͋Δϛυϧ΢ΣΞʹ೚ ͤ·͠ΐ͏ • Fluentd •

    Amazon CloudWatch Logs • Google Cloud Logging
  32. cookiecutter-django΋͓קΊ • cookiecutter͸ςϯϓϨʔτΛݩʹϓϩδΣΫτΛ࡞੒͢Δπʔϧ • URL: https://github.com/pydanny/cookiecutter-django • LOGGINGͷઃఆྫ͸௕͗͢ΔͷͰ͜ͷεϥΠυʹ͸ࡌͤ·ͤΜͰ͠ ͕ͨɺ͜ͷςϯϓϨʔτͰ࡞ͬͨϓϩδΣΫτʹॻ͍͍ͯΔ಺༰Λಡ ΜͰ͍ͩ͘͞

  33. cookiecutter-djangoͷ࢖͍ํ $ pip install cookiecutter # macOSͳΒbrew install cookiecutter ΋Մ

    $ cookiecutter https://github.com/pydanny/cookiecutter-django $ # ʢ৭ʑ࣭໰͞Ε·͕͢ɺͱΓ͋͑ͣ࢖ͬͯΈΔ͚ͩͳΒશ෦EnterΛԡͯ͠OKʣ $ cd my_awesome_project $ ls config/settings __init__.py base.py local.py production.py test.py
  34. ·ͱΊ • settings.py͸؀ڥ͝ͱʹϑΝΠϧΛ෼͚ͯɺ؀ڥม਺ DJANGO_SETTINGS_MODULEͰಡΉϑΝΠϧΛ੾Γସ͑·͠ΐ͏ • ൿີͷ஋Λsettings.pyʹ௚ʹॻ͘ͷ͸ઈରμϝɻ؀ڥม਺͔Βಡ·ͤ·͠ΐ ͏ɻdjango-environ΋͓קΊ • ϩάग़ྗ͸γϯϓϧʹඪ४ग़ྗͷΈɻอଘઌ͸ΞϓϦέʔγϣϯͷ֎ʹ͋Δϛ υϧ΢ΣΞʹ؅ཧͤ͞·͠ΐ͏

    • Ҏ্3఺ΛॳΊ͔Β૊ΈࠐΜͩςϯϓϨʔτcookiecutter-django΋͓קΊͰ͢
  35. ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝· ͨ͠