2012-02-21 3 views
33

У меня есть Django webapp, и я хочу проверить, работает ли он в стеке Heroku (для условного включения отладки и т. Д.) Есть ли простой способ сделать это? Может быть, переменная окружения?Как я могу обнаружить окружающую среду Героку?

Я знаю, что, возможно, я также могу сделать это наоборот, то есть определить, работает ли он на машине-разработчике, но это просто не «правильно звучит».

ответ

21

ENV var представляется наиболее очевидным способом сделать это. Либо искать ENV вар, что вы знаете, существует, или установить свой собственный:

on_heroku = False 
if 'YOUR_ENV_VAR' in os.environ: 
    on_heroku = True 

больше на: http://devcenter.heroku.com/articles/config-vars

+0

Спасибо, я не заметил, что вы еще не могли установить переменные среды. Это похоже на правильный способ сделать это. – aviraldg

+2

ярлык: on_heroku = 'DYNO' в os.environ –

+2

НЕ используйте on_heroku = 'DYNO' в os.environ, как было предложено tinchou. Эта переменная среды не задана во время определенных действий buildpack, например, когда collectstatic автоматически запускается для сборки django. Это невозможно сделать для отладки - вам гораздо лучше использовать вышеупомянутое решение. – patr1ck

16

Подобно тому, что предложил Нил, я хотел бы сделать следующее:

debug = True 
if 'SOME_ENV_VAR' in os.environ: 
    debug = False 

Я видел, как некоторые люди используют if 'PORT' in os.environ: Но, к сожалению, переменная PORT присутствует при локальном запуске foreman start, поэтому нет возможности различать локальное тестирование с мастером и развертыванием на Heroku.

Я также рекомендую использовать один из окр вары что:

  1. Heroku уже из коробки (вместо установки и проверки собственных)
  2. вряд ли можно найти в вашей локальной среда

на дату публикации, Heroku имеет следующие переменные: окружат

['PATH', 'PS1', 'COLUMNS', 'TERM', 'PORT', 'LINES', 'LANG', 'SHLVL', 'LIBRARY_PATH', 'PWD', 'LD_LIBRARY_PATH', 'PYTHONPATH', 'DYNO', 'PYTHONHASHSEED', 'PYTHONUNBUFFERED', 'PYTHONHOME', 'HOME', '_']

Как правило, я использую if 'DYNO' in os.environ:, потому что это, по-видимому, самый специфический для Героку (кто еще будет использовать термин dyno, верно?).

И я также предпочитаю форматировать его, как если-то еще заявление, потому что это более ясно:

if 'DYNO' in os.environ: 
    debug = False 
else: 
    debug = True 
+1

для безопасности вы, вероятно, должны быть 'DEBUG = False' по умолчанию, если вы это делаете. Что-то вроде 'DEBUG = False; если не «DYNO» в os.environ: debug = True' возможно? – crobar

0

Подробнее об этом здесь: https://devcenter.heroku.com/articles/config-vars

Мое решение:

$ heroku config:set HEROKU=1 

Эти переменные среды постоянны - они останутся на месте во всех развертываниях и перезагрузках приложений, поэтому, если вам не нужно изменять значения, вам нужно только установить их один раз.

Затем вы можете проверить его присутствие в своем приложении.:

>>> 'HEROKU' in os.environ 
True 
10

Сначала установите переменную окружения ON_HEROKU на Heroku:

$ heroku config:set ON_HEROKU=1 

Тогда в settings.py

import os 

# define if on heroku environment 
ON_HEROKU = 'ON_HEROKU' in os.environ 
+0

Я предпочитаю решение 'DYNO' (или устанавливаю его в веб-интерфейсе, а не в' config: set'), так как это будет 'True' на' heroku local' тоже, то есть мы не сможем его использовать, чтобы проверить, на локальном хосте или нет. – OJFord

+0

@OllieFord Я не получаю 'DYNO' на' heroku local', поэтому мне пришлось явно добавить 'DYNO = Dummy' в мой' .env' (Любое значение отлично, поскольку мы проверяем наличие только env. переменная) –

-1

Короткая версия: проверьте, что часовой пояс 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)' 

Это более консервативно, чем if tz=='UTC\n': если есть сомнения, предположите, что мы в производстве. Обратите внимание, что мы сохраняем часовой пояс для переменной среды, так как settings.py может выполняться более одного раза. На самом деле сервер разработки выполняет его дважды, а во второй раз системный часовой пояс уже «UTC» (или что-то еще в settings.TIMEZONE).

Длинная версия:

делает абсолютно уверен, что мы никогда не работать на Heroku с DEBUG=True, и что мы никогда не запускать сервер разработки на Heroku даже с DEBUG=False. Из 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() 

Если вы действительно хотите запустить сервер разработки на Heroku, я предлагаю вам добавить переменную среды с указанием даты, когда вы можете сделать это. Тогда продолжайте, если эта дата сегодня. Таким образом вам придется изменить эту переменную до начала разработки, но если вы забудете ее отменить, на следующий день вы все равно будете защищены от случайного запуска ее в процессе производства. Конечно, если вы хотите быть суперконсервативным, вы также можете указать, скажем, 1-часовое окно, когда применяются исключения.

Наконец, если вы решили принять подход, предложенный выше, в то время как вы на него, а также установить Джанго-безопасности, добавьте djangosecurity к INSTALLED_APPS, и добавить в конце вашего 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 
-1

DATABASE_URL переменной окружения

in_heroku = False 
if 'DATABASE_URL' in os.environ: 
    in_heroku = True 

Я думаю, что вам нужно включить базу данных для приложения с:

heroku addons:create heroku-postgresql:hobby-dev 

но он бесплатный и, скорее всего, то, что вы собираетесь делать в любом случае.

Heroku делает эту переменную доступны при запуске своих приложений, в частности, для использования в качестве:

import dj_database_url 
if in_heroku: 
    DATABASES = {'default': dj_database_url.config()} 
else: 
    DATABASES = { 
     'default': { 
      'ENGINE': 'django.db.backends.sqlite3', 
      'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 
     } 
    } 

Не несложный, как эта переменная может быть определена локально, но удобно для простых случаев.

heroku run env 

могут также показать другие возможные переменные, такие как:

  • DYNO_RAM
  • WEB_CONCURRENCY

, но я не уверен, если таковые документированы как DATABASE_URL.

+0

@ Даунвотеры, пожалуйста, объясните, чтобы я мог узнать и улучшить информацию ;-) –

+0

Переменная среды 'DATABASE_URL' становится все более распространенной и не используется только Heroku. С течением времени все меньше и меньше шансов быть точным. – Rebs

0

Самый надежный способ - установить переменную среды, как указано выше. Если это не возможно, есть несколько признаков, вы можете искать в файловой системе, но они не могут быть/не являются абсолютно надежным

  • Heroku экземпляров всех есть путь /app - файлы и скрипты, которые выполняются будет также под этим, поэтому вы можете проверить наличие каталога и/или сценарии, которые запускаются из-под него.

  • Существует пустой каталог /etc/heroku

  • /etc/hosts может иметь некоторые Heroku связанные домены добавлены ~ $ cat /etc/hosts <snip>.dyno.rt.heroku.com

Любой из них может и может измениться в любой момент.

Ваше имущество может отличаться от

Смежные вопросы