発端
Dockerで、Djangoコンテナ+uWSGI(Emperorモード)コンテナ+Postgresコンテナ、という構成にしてて、direnvで管理していたPostgresの接続情報でアプリ側から繋がらない現象にハマった
1 | psycopg2.OperationalError: could not connect to server: No such file or directory |
環境
1 | Django==2.0.5 |
原因
結論から言うと、.envrc
で管理している環境変数が、uWSGIコンテナだけ反映されていなかった
調べていく過程で「そらそうやわ」ってなったんだけど、当時切り分けのために実施した内容をまとめると
manage.py migrate
は問題ない(※実際にスキーマが出来てる)- ブラウザからのアクセスでエラーになる
なんていうややこしい状態になった
これは、wsgi.py
を動かしているuWSGIコンテナ側には、direnvの.envrc
に記述した以下の内容が反映されていないために出ている事が分かった
1 | $ cat .envrc |
考えた
解決方法としてどんな方法があるのか考えてみた
- uWSGIコンテナ側で環境変数を管理し、起動コマンドで環境変数を渡す
- Djangoコンテナ側で、環境変数の管理方法を変える
1つ目の方法は、たとえdocker-compose.yml
側に書いて管理したとしても、アプリ数が増えていくと、どんどん肥大化していってしまうので、やっぱりDjangoコンテナ側でなんとかするのがいいのかなぁという結論になりました
direnvは特性上、コマンドライン上でpython manage.py
する時だけは環境変数が問題なくセットされるが、uWSGIコンテナ側では当然反映されないので、じゃあDjangoコンテナ側で環境変数ロード出来る仕組みを作ればいいのか、そういえば、dotenvとかあったなー、というところに帰結し、乗り換えました
dotenv: インストール
1 | $ pip install python-dotenv |
dotenv: .envを作成
1 | $ vim .env |
1 | DB_HOST=[Postgresコンテナ] |
dotenv: .envの読み込み
修正箇所は、setting.py
のみです
1 | $ vim settings.py |
1 | import os |
おわりに
今思えば、Python3+Django1.10+Nginx+uWSGIでMySQLに接続するまでのメモで似たような事をしているので、wsgi.py
使う勢は覚えといたほうがよいのかもしれない