仕事でwebアプリケーションを作成しています。
Djangoで作成し、webサーバをApache、環境をpipenvで設定したpython3環境上で動かす予定です。
Apacheが起動するまでに、苦労しましたのでメモ的に残しておきます。web検索すると、pipenv上で動かしているのが見当たらなかったので。
前提
- 仕事の制約で、python3は別ディレクトリ( /usr/local/python36/ )にインストールしている。
- 別ディレクトリにインストールするため、RPMを作成
- mod_wsgi.soはpython3のRPMをインストール後、pipでインストール
mod_wsgi.soもRPMでインストールするように設定済み
Aapcheの設定
- いわゆる「デーモンモード」で設定
- WSGIRestrictEmbedded: 設定したほうがいいと書いてあったので設定
- LoadModule: mod_wsgi.soはあらかじめ入れておいたので、インストールしたディレクトリを設定
- WSGIPythonHome: pipenv用設定。先に、PIPENV_VENV_IN_PROJECT=1が必要。でないと/homeに作成してしまう。
- WSGIDaemonProcess projectはなんでもいい。あとは使用するpython-pathを列挙する。
- WSGIScriptAlias: wsgi.pyファイルを指定
- WSGIProcessGroup: Directoryで指定したWSGIProcessGroupと同じにしておけばいいらしい。
/etc/httpd/conf.d/app.conf
WSGIRestrictEmbedded On LoadModule wsgi_module /usr/local/python3/lib/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so WSGIPythonHome /opt/app/.venv WSGIDaemonProcess project threads=5 python-path=/usr/local/python3/lib/:/usr/local/python3/lib/python3.6/site-packages/ #Pointing wsgi script to config file WSGIScriptAlias /app /opt/app/website/wsgi.py WSGIProcessGroup app Alias /app/static/ "/opt/app/static/" <LocationMatch "\.(jpg|gif|png|js|css)$"> SetHandler None </LocationMatch> <Directory /opt/app > WSGIProcessGroup app WSGIApplicationGroup app Order deny,allow Allow from all </Directory>
/etc/sysconfig/httpd
LD_LIBRARY_PATH=/usr/local/python3/lib:/usr/local/lib
インストール準備は以下のように行いました。
$ export LD_LIBRARY_PATH="/usr/local/python3/lib/" ### Webアプリをインストールするディレクトリ $ cd /opt/app $ export PIPENV_VENV_IN_PROJECT=1 $ export PATH="/usr/local/python3/bin/:$PATH" $ pipenv install $ pipenv run python3 manage.py migrate
環境ごとの設定値を有効にする機構
Djangoを環境ごと(開発/ステージング/本番)に別設定をさせる機構として、DJANGO_ENVIRONMENTをチェックするような機構を採用していました。
DJANGO_ENVIRONMENTをApacheでも有効にするために https://stackoverflow.com/questions/19754834/access-apache-setenv-variable-from-django-wsgi-py-file のような
WSGIEnvironmentを使用する方法が記述されていますが、試してみたところ、残念ながら、私の環境では、出来ませんでした。
というのも、私の場合、以下のようなdjango.setupを行う「前に」環境変数を指定する必要があったので動作しなかったです。前に設定しないと、マイグレーションが動作しないという罠がありました。DBを使用しているので、そのDB設定がまさに、環境によって違うという。。
django.setup(set_prefix=False)
上記の機構自体は動作するので、django.setup()の「後」に環境変数を設定していいのであれば動作すると思います。
なお、私が行った対処としては、wsgi.pyの中で環境変数を設定するコードを実装することです。以下のような感じで。ベタだけど、他にあまりいい方法がなかった。。
environ = 'dev' ### 条件により変更 if a == True: environ = 'stg' os.environ["DJANGO_ENVIRONMENT"] = environ
DJANGO_ENVIRONMENTは、ちゃんと影響している模様。