Подтвердить что ты не робот

Как я могу определить среду Heroku?

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

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

4b9b3361

Ответ 1

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

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

more at: http://devcenter.heroku.com/articles/config-vars

Ответ 2

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

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

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

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

  • У Heroku есть своя версия (вместо настройки и проверки для вашего).
  • вряд ли будет найден в вашей локальной среде.

В момент публикации 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:, потому что это, по-видимому, самый специфичный для Heroku (кто еще будет использовать термин dyno, верно?).

И я также предпочитаю форматировать его как оператор if-else, потому что он более явный:

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

Ответ 3

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

$ heroku config:set ON_HEROKU=1

Тогда в settings.py

import os

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

Ответ 4

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

Мое решение:

$ heroku config:set HEROKU=1

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

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

>>> 'HEROKU' in os.environ
True

Ответ 5

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

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

  • Существует пустая директория /etc/heroku

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

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

Ваше перемещение может варьироваться

Ответ 6

Краткая версия: проверьте, что часовой пояс 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-часовое окно, когда применяются исключения.

Наконец, если вы решили применить предложенный выше подход, пока вы на нем, установите django-security, добавьте 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

Ответ 7

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.