How can I detect Heroku's environment?

前端 未结 7 1636
Happy的楠姐
Happy的楠姐 2020-12-24 05:40

I have a Django webapp, and I\'d like to check if it\'s running on the Heroku stack (for conditional enabling of debugging, etc.) Is there any simple way to do this? An envi

相关标签:
7条回答
  • 2020-12-24 06:19

    Short version: check that the time zone is UTC/GMT:

    if not 'ORIGINAL_TIMEZONE' in os.environ:
        f = os.popen('date +%Z')
        tz = f.read().upper()
        os.environ['ORIGINAL_TIMEZONE']=tz
    
    
    tz = os.environ['ORIGINAL_TIMEZONE']
    if tz != '' and (not 'utc' in tz.lower()) and (not 'gmt' in tz.lower()):
        print 'Definitely not running on Heroku (or in production in general)'
    else:
        print 'Assume that we are running on Heroku (or in production in general)'
    

    This is more conservative than if tz=='UTC\n': if in doubt, assume that we are in production. Note that we are saving the timezone to an environment variable because settings.py may be executed more than once. In fact, the development server executes it twice, and the second time the system timezone is already 'UTC' (or whatever is in settings.TIMEZONE).

    Long version:

    making absolutely sure that we never run on Heroku with DEBUG=True, and that we never run the development server on Heroku even with DEBUG=False. From settings.py:

    RUNNING_DEV_SERVER = (len(sys.argv) > 1) and (sys.argv[1] == 'runserver')
    
    DEBUG = RUNNING_DEV_SERVER
    
    TEMPLATE_DEBUG = DEBUG
    
    # Detect the timezone
    if not 'ORIGINAL_TIMEZONE' in os.environ:
        f = os.popen('date +%Z')
        tz = f.read().upper()
        os.environ['ORIGINAL_TIMEZONE']=tz
        print ('DEBUG: %d, RUNNING_DEV_SERVER: %d, system timezone: %s ' % (DEBUG, RUNNING_DEV_SERVER, tz))
    
    
    if not (DEBUG or RUNNING_DEV_SERVER):
        SECRET_KEY = os.environ['SECRET_KEY']
    else:
        print 'Running in DEBUG MODE! Hope this is not in production!'
    
        SECRET_KEY = 'DEBUG_INSECURE_SECRET_KEY_ae$kh(7b%$+a fcw_bdnzl#)$t88x7h2-p%eg_ei5m=w&2p-)1+'
    
        # But what if we are idiots and are still somehow running with DEBUG=True in production?!
        # 1. Make sure SECRET_KEY is not set
        assert not SECRET_KEY in os.environ
        # 2. Make sure the timezone is not UTC or GMT (indicating production)
    
        tz = os.environ['ORIGINAL_TIMEZONE']
        assert tz != '' and (not 'UTC' in tz) and (not 'GMT' in tz)
    
        # 3. Look for environment variables suggesting we are in PROD
        for key in os.environ:
            for red_flag in ['heroku', 'amazon', 'aws', 'prod', 'gondor']:
                assert not red_flag in key.lower()
                assert not red_flag in os.environ[key].lower()
    

    If you really want to run the development server on Heroku, I suggest you add an environment variable specifying the date when you can do that. Then only proceed if this date is today. This way you'll have to change this variable before you begin development work, but if you forget to unset it, next day you will still be protected against accidentally running it in production. Of course, if you want to be super-conservative, you can also specify, say, a 1-hour window when exceptions apply.

    Lastly, if you decided to adopt the approach suggested above, while you are at it, also install django-security, add djangosecurity to INSTALLED_APPS, and add to the end of your settings.py:

    if not (DEBUG or RUNNING_DEV_SERVER):
        ### Security
        SECURE_SSL_REDIRECT = True
        SECURE_CONTENT_TYPE_NOSNIFF = True
    
        SECURE_HSTS_SECONDS = 86400000
        SECURE_HSTS_INCLUDE_SUBDOMAINS = True
        SECURE_BROWSER_XSS_FILTER = True
    
        SESSION_COOKIE_SECURE = True
        SESSION_COOKIE_HTTPONLY = True
        CSRF_COOKIE_HTTPONLY = True # May have problems with Ajax
        CSRF_COOKIE_SECURE = True
    
    0 讨论(0)
提交回复
热议问题