1

Я пытаюсь настроить приложение Django/DRF на Elastic Beanstalk, и по какой-либо причине Django просто не может видеть желаемые переменные среды. Когда я войти, я могу видеть, что они просто отлично, с помощьюDjango не видит переменные окружения при развертывании на Elastic Beanstalk

$ eb ssh 
$ cat /opt/python/current/env 

Я также могу их видеть, за исключением относительно чувствительные, связанных с RDS, просто используя $eb printenv.

Все, что кажется настроенным и работоспособным. Тем не менее, Django любит читать среду сразу при запуске, и кажется, что переменные окружения просто еще не установлены. Я экспериментировал с просто введением print(os.environ) в settings.py, и когда я это делаю, я обнаруживаю целую кучу переменных среды, которые мне не нужны (например, 'SUPERVISOR_GROUP_NAME': 'httpd'), и ни один из тех, которые я установил сам, например DJ_SECRET_KEY.

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

[Wed Nov 23 15:56:38.164153 2016] [:error] [pid 15708] DJ_SECRET_KEY not in environment; falling back to hardcoded value. 
[Wed Nov 23 15:56:38.189717 2016] [:error] [pid 15708] RDS_DB_NAME not in environment; falling back to sqlite 
[Wed Nov 23 15:56:38.189751 2016] [:error] [pid 15708] AWS_STORAGE_BUCKET_NAME not in environment; falling back to local static storage. 

Опять же, эти переменные устанавливаются в настройки, и они появляются с любым другим инструментом отчетности, который дает EB. Они просто не установлены для Django, чтобы читать их, когда он запускает и читает settings.py.

This выглядит довольно близко к этой проблеме, но это не совсем то же самое: я знаю, как видеть/загружать переменные среды в оболочку при ssh-ing в eb-экземпляр; они просто не появляются, когда я нуждаюсь в них для фактического проекта.

This - это почти то же самое, что у меня есть, но принятый правильный ответ не имеет для меня никакого смысла, и верхний проголосовавший ответ не применяется; эти файлы уже находятся в git.

Как настроить параметры, чтобы Django мог видеть переменные среды?

+0

Не уверен относительно эластичного бобового стебля, но я столкнулся с подобной проблемой при настройке своих проектов Django с помощью Apache/Nginx. И я должен был установить переменные среды в своих файлах конфигурации. Может быть, это должно быть применимо и здесь. –

+0

Что вы пытаетесь достичь? – Gustaf

+0

@Gustaf Я пытаюсь использовать переменные среды для настройки Django. Например, с учетом ассоциированного экземпляра RDS, EB автоматически устанавливает несколько переменных, таких как 'RDS_DB_NAME', с которыми можно подключиться к этой базе данных. Проблема в том, что эти переменные не заданы во время чтения Django. Решение может быть методом, с помощью которого мы можем задержать инициализацию WSGI до тех пор, пока не будут установлены все переменные среды. В конце концов, все они будут установлены, но, видимо, не скоро. – coriolinus

ответ

2

Учитывая, что в магазинах EB все эти переменные среды в каноническом месте как Баш скрипт, я в конечном итоге просто иметь Баш выполнить скрипт , и обновление среды от анализируемых результатов.

Я создал файл get_eb_env.py параллельно с моим settings.py.Его основное содержание:

import os 
import subprocess 

ENV_PATH = '/opt/python/current/env' 

def patch_environment(path=ENV_PATH): 
    "Patch the current environment, os.environ, with the contents of the specified environment file." 
    # mostly pulled from a very useful snippet: http://stackoverflow.com/a/3505826/504550 
    command = ['bash', '-c', 'source {path} && env'.format(path=path)] 

    proc = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True) 
    proc_stdout, _ = proc.communicate(timeout=5) 

    # proc_stdout is just a big string, not a file-like object 
    # we can't iterate directly over its lines. 
    for line in proc_stdout.splitlines(): 
     (key, _, value) = line.partition("=") 
     os.environ[key] = value 

Тогда я просто импортирую и называю patch_environment() возле головы моей settings.py.

+0

, который работал как шарм. Только одно: в моем EB запуске python 2.7.12 'proc.communicate' не принимает аргумент' timeout'. У вас есть какие-то объяснения? Тем не менее, ты сделал свой день. –

+0

Я запускал Python 3.4 для этого; аргумент 'timeout' был введен IIRC в Python 3.2. Если вам нужна эта функция на более раннем Python, вы можете рассмотреть обратный порт [subprocess32] (https://pypi.python.org/pypi/subprocess32/). – coriolinus

0

Это не то, о чем вы просите, но я надеюсь, что это все равно решит вашу проблему.

Я использую множество переменных окружения в настройках. Я думаю, что Elastic Beanstalk устанавливает все до того, как он запускает команды контейнера, и такие, и переменные недоступны, и поэтому ваш журнал показывает их пустыми. Но вам действительно нужны переменные в этот момент?

Вы не можете устанавливать любые локальные параметры разработки, необходимые в файле local_settings.py, и не допускать это из-за контроля версий.

Мы используем их так.

if 'DB_HOST' in os.environ: 
    DATABASES = { 
     'default': { 
      'ENGINE': 'django.db.backends.mysql', 
      'NAME': 'ebdb', 
      'USER': 'ebroot', 
      'PASSWORD': 'ebpassword', 
      'HOST': os.environ['DB_HOST'], 
      'PORT': '3306', 
     } 
    } 

try: 
    from local_settings import * 
except ImportError: 
    pass 

Они также доступны при запуске container_commands:

container_commands: 
    01_do_something: 
    command: "do_something_script_{$PARAM1}.sh" 
+0

Нам нужны переменные окружения. Ваш пример демонстрирует именно то, почему. У меня есть что-то очень похожее на то, что в моем 'settings.py', за исключением того, что он возвращается к базе данных Sqlite вместо MySql на localhost. Развертывание этой установки на EB _always_ заканчивается запуском Sqlite, не соответствующим правильному подключению к общей базе данных. Это не то поведение, которое мы хотим для производственной среды! – coriolinus

+0

У вас нет другого файла, у нас есть файл локальных настроек. Позвольте мне уточнить свой ответ. – Gustaf

1

Я решил проблему с изменением ключа «DJANGO_AWS_SECRET_ACCESS_KEY», потому что DJANGO сгенерировал ключ с кавычками (`) и интерпретировал его как команду.