Django - Не могу передать переменную окружения в Apache/Passenger через интерфейс WSGI
Я ищу решение, я не могу передать apache определение переменной в /etc/profile.
Вот что я пытаюсь установить:
У меня есть приложение django, которое я развертываю через Apache/Passenger (modrails) через интерфейс WGSI.
В моем файле settings.py я использую эту команду python: ENVIRONMENT = os.getenv('ENV', 'PROD'), поэтому, если переменная ENVIRONMENT не определена, она по умолчанию переходит к производственным настройкам.
Это помогает мне управлять базой данных, к которой я подключаюсь, и активировать средства отладки.
Он работает в рабочей среде, потому что это значения по умолчанию, когда я нахожусь на сервере DEV, я не могу получить переменную среды из /etc/profile.
Это на сервере Ubuntu 10.04
Итак, вот какой тест я сделал:
1) положить в /etc/profile -> ENV='DEV' экспорт ENV
2) в /etc/profile.d/environment.sh -> #!/ Bin/sh ENV='DEV' экспортировать ENV
3) в моем файле конфигурации виртуального хоста -> PassEnv ENV
4) все еще в моем файле конфигурации виртуального хоста -> SetEnv ENV DEV
5) пассажир требует, чтобы passenger_wgsi.py зарегистрировал ваше заявление, если я принудительно ввел в этот файл viron['ENV'] = 'DEV', это пошло на работу, но я не могу этого сделать
ENVIRONMENT = os.getenv('ENV', 'PROD')
os.environ['ENV'] = ENVIRONMENT
Любая идея, почему или как я могу это исправить? благодарю вас!
@Josh
Спасибо за ответ. Но у меня все еще есть некоторые вопросы.
В Passenger единственной вещью, которую я должен был установить в файле виртуального хоста, было расположение общей папки внутри моего приложения python / django. Так что мой файл виртуального хоста будет выглядеть так.
DocumentRoot path_to_my_public_folder # /home/user/workspace/myapp/public
Тогда внутри папки myapp есть passenger_wsgi.py
которые определяют очень мало, как вы сказали:
import sys, os
sys.path.append(os.getcwd())
os.environ['DJANGO_SETTINGS_MODULE'] = "myapp.settings"
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
и после этих настроек это было, приложение работало. Так что, возможно, я пропускаю ваши показания, когда вы говорите, что мы должны указать, какой файл wsgi мы использовали. Я думал, что он непосредственно найдет passenger_wsgi.py и загрузит его по умолчанию, как, кажется, он делает в данный момент.
Еще одна вещь, которую вы должны знать, это то, что наш проект находится в репозитории SVN, и я хочу настроить этот файл для многих пользователей, чтобы у нас не было других настроек.
Но то, что я буду тестировать завтра, - это идея иметь один базовый файл wsgi с общей информацией и базой на имени хоста компьютера. Я буду импортировать остальные настройки, например, dev_wsgi.py или prod_wsgi.py.
Я должен быть в состоянии получить это имя с помощью Python и основываться на имени, которое я буду устанавливать переменные, которые мне нужно использовать.
Спасибо за идею, это хорошо ценится.
2 ответа
Я собираюсь предложить альтернативное решение, так как я не знаю, как решить вашу конкретную проблему.
Создайте несколько файлов WSGI. production.wsgi
, dev1.wsgi
, dev2.wsgi
, test.wsgi
и т. д. Каждый веб-сервер должен быть настроен с /path/to/.wsgi
тем не мение. В любом случае, в файле wsgi содержится минимальное количество кода, поэтому его копирование не очень дорого. Кроме того, вы могли бы иметь _base.wsgi
предоставить все общие значения, и потребовать, чтобы производный WSGIS позвонил application = wsgi.WSGIHandler()
,
Каждый разработчик в нашем проекте имеет свои собственные файлы настроек и файлы wsgi, чтобы позволить вмешиваться в настройки, даже не имея возможности нарушить производство с мошенническим значением.
Я наконец заставил это работать, и я предоставлю способ, которым я понял это после предложения @Josh.
Вот что сейчас выглядит как мой файл WSGI:
import sys, os
sys.path.append(os.getcwd())
# this allows us to run the project under Passenger on our workstation
# it is simply a list of all the developers machine hostname it can be expended as we want
LIST_OF_DEV_HOSTNAME = ['PC1', 'PC2','PC3',]
# Return the current machine hostname
HOSTNAME = os.uname()[1]
# Import Django app module
if HOSTNAME in LIST_OF_DEV_HOSTNAME:
# here if it is not detected you can append to your python path the root folder of your django app
sys.path.append('/home/user/workspace/django-app')
# As previously mentioned I use an Environment Variable in the settings.py to switch DB and debug settings
# so here I set the ENV variable I use in the settings.py to reflect the Development environment
os.environ['ENV'] = 'DEV'
else:
# we could append any other needed path in here too
sys.path.append('/any/other/folder')
# As previously mentioned I use an Environment Variable in the settings.py to switch DB and debug settings
# so here I set the ENV variable I use in the settings.py to reflect the Development environment
os.environ['ENV'] = 'PROD'
# Shared between the two environments
sys.path.append('/usr/lib/python2.4/site-packages/')
# Import the django app settings and Environment variable
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Вот так я получил его на тренировку.
Я также смог добиться этого, создав файл типа /opt/environment и выполнив следующую проверку: # проверить, существует ли файл, если os.path.isfile('/opt/environment'): os.environ['ENV'] = 'DEV' else: os.environ['ENV'] = 'PROD'
это позволило бы мне выполнить ту же проверку, но я должен был бы сказать всем создать файл. Это зависит от того, что вы хотите сделать, создать файл или добавить имя вашего хоста в список, так как наш проект находится в SVN, простая фиксация нашего WSGI-файла для меня более проста, чем создание файла.
Спасибо.