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

Stop writing settings files

Stop writing settings files

Bruno Renié

May 15, 2013
Tweet

More Decks by Bruno Renié

Other Decks in Programming

Transcript

  1. Stop writing
    settings
    files

    View Slide

  2. Settings

    View Slide

  3. local_settings
    # settings.py
    # settings goes here, and at the end…
    try:
    from local_settings import *
    except ImportError:
    pass

    View Slide

  4. # settings.py
    INSTALLED_APPS = …
    # local_settings.py
    INSTALLED_APPS = …
    How do I know what's
    in the base settings?

    View Slide

  5. # settings/base.py
    INSTALLED_APPS = …
    # settings/production.py
    from .base import *
    # override here with
    # production-specific settings
    Multiple settings files
    $ python manage.py shell --settings=settings.production

    View Slide

  6. settings/
    __init__.py
    base.py
    dev.py
    staging.py
    production.py
    other.py
    stuff.py
    whatever.py

    View Slide

  7. — 12factor.net
    " "
    … strict separation of config from
    code. Config varies substantially
    across deploys,code does not.

    View Slide

  8. Expose your configuration
    as environment variables
    Derive your settings from
    the environment
    DEBUG = bool(os.environ.get('DEBUG', False))
    Use one settings file

    View Slide

  9. ALLOWED_HOSTS
    AWS_ACCESS_KEY_ID
    AWS_SECRET_ACCESS_KEY
    DATABASE_URL
    DJANGO_SETTINGS_MODULE
    EMAIL_URL
    FROM_EMAIL
    HTTPS
    MEDIA_ROOT
    REDIS_URL
    SECRET_KEY
    SENTRY_DSN
    STATIC_ROOT

    View Slide

  10. What about development?
    Aren't environment variables a
    pain to work with?

    View Slide

  11. daemontools' envdir
    path/to/env/
    DATABASE_URL
    SENTRY_DSN

    $ envdir path/to/env
    $ envdir path/to/env django-admin.py
    Sane defaults for development
    kept under version control

    View Slide

  12. envdir in ur manage.py
    if __name__ == "__main__":
    if 'test' in sys.argv:
    env_dir = os.path.join('tests', 'envdir')
    else:
    env_dir = 'envdir'
    env_vars = glob.glob(os.path.join(env_dir, '*'))
    for env_var in env_vars:
    with open(env_var, 'r') as env_var_file:
    os.environ.setdefault(env_var.split(os.sep)[-1],
    env_var_file.read().strip())
    from django.core.management import execute_from_command_line
    execute_from_command_line(sys.argv)

    View Slide

  13. One settings files, less moving parts
    Configuration as environment variables
    Production: set them with
    daemontools, circus, supervisor…
    Development: use envdir and/or
    a custom manage.py
    Your PaaS already supports them
    Easy to setup with Salt/Puppet/Chef
    Your sysadmin will thank you

    View Slide

  14. thanks!
    @brutasse

    View Slide