Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
70
Help us understand the problem. What is going on with this article?
@moonwalkerpoday

Djangoで環境変数?ならdjango-environを使おうか。

More than 3 years have passed since last update.

バックエンドを開発していると、秘密にしたい値がどうしてもでてきますよね。
AWSのシークレットキー・APIキー・DBの接続情報等…
ただ、それをsettings.pyでハードコードしてGitで管理というのは楽ですが正直セキュリティ的によろしくありません。

となると、「環境変数で管理しよう」となってくる事が多いと思いますが、
単純に環境変数にすると開発環境での管理が面倒になる場合もあります。

とりあえず環境変数にした場合の罠

開発環境はMac。
IDEはPythonista御用達のPyCharmを使います。

環境変数設定ファイルを作成

.env
# MySQL
DB_NAME=db_name
DB_PASSWORD=hogepass
DB_USER=hogehoge
DB_HOST=127.0.0.1
DB_PORT=3306
DB_ENGINE=django.db.backends.mysql

# AWS Settings
DJANGO_AWS_S3_BUCKET_NAME=huga-storage
DJANGO_AWS_ACCESS_KEY=xxxxxxxxxxxxxxxxxx
DJANGO_AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxx

settings.pyを編集

settings.py
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

・・・

AWS_S3_BUCKET_NAME=os.environ['DJANGO_AWS_S3_BUCKET_NAME']
AWS_ACCESS_KEY=os.environ['DJANGO_AWS_ACCESS_KEY']
AWS_SECRET_KEY=os.environ['DJANGO_AWS_SECRET_KEY']

DATABASES = {
    'default': {
        'ENGINE': os.environ['POSTGRES_ENGINE'],
        'NAME': os.environ['POSTGRES_NAME'],
        'USER': os.environ['POSTGRES_USER'],
        'PASSWORD': os.environ['POSTGRES_PASSWORD'],
        'HOST': os.environ['POSTGRES_HOST'],
        'PORT': os.environ['POSTGRES_PORT'],
    }
}

・・・

と、こんな感じでしょうか。

問題点

  • コマンドラインから行う時はMacの環境変数にセットしなければならない。
  • Macの環境変数にセットしてなかったらPycharmRun/Debug Configrationsで環境変数をいちいち指定しないといけない。

たかが2点されど2点。
まずLinux運用想定で.envを作成したとしても、Macだとexportしないと環境変数に登録できないし…
↓のようなシェルスクリプト作成して環境変数修正するたびに実行してなんてしたくない。

env.sh
#!/bin/sh
# ファイルを1行ずつ読み込んで表示

TESTFILE=./.env
while read line; do
    export $line
done < $TESTFILE

という事で、こんな無駄をなくしましょう。

django-environを使用する

Github
https://github.com/joke2k/django-environ
ありがたや(-人-)

導入

$ pip install django-environ

環境変数設定ファイルを修正

.env
# MySQL
DATABASE_URL=mysql://hogehoge:hogepass@127.0.0.1:3306/db_name

# AWS Settings
DJANGO_AWS_S3_BUCKET_NAME=huga-storage
DJANGO_AWS_ACCESS_KEY=xxxxxxxxxxxxxxxxxx
DJANGO_AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxx

settings.pyを改善

settings.py
import environ

# settings.pyの位置を起点として3つ上の親ディレクトリを参照。
BASE_DIR = environ.Path(__file__) - 3

env = environ.Env()

# 環境変数でDJANGO_READ_ENV_FILEをTrueにしておくと.envを読んでくれる。
READ_ENV_FILE = env.bool('DJANGO_READ_ENV_FILE', default=False)
if READ_ENV_FILE:
    env_file = str(BASE_DIR.path('.env'))
    env.read_env(env_file)

・・・

AWS_S3_BUCKET_NAME=env('DJANGO_AWS_S3_BUCKET_NAME')
AWS_ACCESS_KEY=env('DJANGO_AWS_ACCESS_KEY')
AWS_SECRET_KEY=env('DJANGO_AWS_SECRET_KEY')

DATABASES = {
    'default': env.db() # デフォルトでDATABASE_URLの環境変数を分解してくれる
}

・・・

ポイント

  • Macに環境変数を設定しなくても、1つ環境変数をTrueにしておけば .env を読んでくれる。
  • DATABASE_URLという環境変数で一行書くことでDBの定義ができる
  • ディレクトリのベースディレクトリ定義などがスッキリする。

ちなみに、DB以外にもキャッシュとかもワンラインで定義できます。
DJANGO_READ_ENV_FILEをTrueにしておけば.envを修正しても毎回読み直してくれるのでかなり便利です。

まとめ

使用したメソッドは一例ですが、これだけでもスッキリしたコードになりました。
環境変数にする事によりセキュリティ対策にもなるし、開発と本番とかでsettingsファイルを切り替える必要もなくなります。
OSSは日に日に追加・改善等が進められているので、いつのまにか痒い所に手が届くライブラリが作成されているという事が無いようにしていく事が大切ですね。
そして人様が開発したライブラリに頼りきるのではなく、自らも積極的にOSSに貢献していきましょう!

Let's OSS Life!!!

70
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
moonwalkerpoday
ライン作業員(地獄)➔営業(出版/製本 or Web)➔PHPer(オレオレフレームワーク)➔Pythonista 一児を持つパパエンジニアです。現在シワの残らないアイロンのかけ方を修行中。
jsl
株式会社日本システム技研は、1976年に設立した長野に本社を構えるIT企業です。主にPython/Djangoの使用したWebアプリケーションの受託開発とプロダクト開発を行なっています。エンジニア向けコミュニティGEEKLAB.NAGANO( http://geeklab-nagano.com ) の運営をしています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
70
Help us understand the problem. What is going on with this article?