Django AmazonS3 Heroku でデプロイした時の話 前編
参照サイト
全て以下のリンクのおかげです。
めちゃめちゃわかりやすいです! 上記を元に進めて、こちらで設定に困った箇所を中心に編集していきます。
前編
S3の設定について
名前をdesigntoollab と設定した場合のポリシーの追加。 "Principal" が必須のようなので、以下のように設定しておく。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::designtoollab", "arn:aws:s3:::designtoollab/*" ] } ] }
s3 ウェブサイトのホスティングを有効にする。
静的ウェブサイトホスティング->インデックスドキュメント->index.html
を設定する。
AWSのクレデンシャル
環境変数AWS_ACCESS_KEY_IDとAWS_SECRET_ACCESS_KEYで渡します。 .envは、manage.pyと同じフォルダに置いておきます。
.env
AWS_ACCESS_KEY_ID=*** AWS_SECRET_ACCESS_KEY=***
- アクセスキーの取得方法は以下のサイト参照
awsのs3を操作する為のaccess keyとsecret keyを取得する(IAM) | joppot
.botoをmanage.pyと同じフォルダに作成する。
[s3] host = s3-ap-northeast-1.amazonaws.com
上記はリージョン東京の例なので、それ以外の地域の場合は別のリージョンのホストに修正する。
wsgi.pyを設定する
whitenoiseを適用させる。
Django and Static Assets | Heroku Dev Center
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ecommerce.settings") from django.core.wsgi import get_wsgi_application from whitenoise.django import DjangoWhiteNoise application = get_wsgi_application() application = DjangoWhiteNoise(application)
ここまで終わったら、もう一度herokuのページに行って設定をすすめてみる。
pip freeze > requirements.txt
でpip installされているモジュールを書き込む。
Procfileを、manage.pyと同じフォルダに作成する。
web: gunicorn アプリ名.wsgi --log-file -
pip install -r requirements.txt
で必要なファイルをlocalにinstallする
heroku local web
で起動させてみる。
.gitignoreをmanage.pyと同じフォルダに作成する
venv *.pyc staticfiles .env
git push heroku master
でアップする。
エラーが出てしまった場合
error no30 の場合
OSError: [Errno 30] Read-only file system: '/static_in_env'
collectstaticの時のerror。いろいろ原因はあるが、フォルダ自体が無いことが原因だと思われる。フォルダが無い原因は、settings/production.pyが読み込まれてなかったことだと思われる。なので、settings/init.py を以下のように修正した。
from .base import * from .production import *
これで強制的にproductionを読み込ませられる。
ImportError: No module named 'ecommerce2.settings.db_password'
productionを読み込ん時に上記のようなerrorが表示されてしまった。。。これは単純にproduction用のdatabaseをセットするのを忘れていたorz
なので、databaseを設定する。 dj_database_urlを利用すると便利らしい!
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # update db settings import dj_database_url db_from_env = dj_database_url.config(conn_max_age=400) DATABASES['default'].update(db_from_env)
今回は、base.pyで、すでにDATABASESの設定はしてあるので、update db settingsだけ追記しても良さそうだが、なぜかerrorが出るので、production.pyにも同じ設定を書いておく。
これで試してみる。
errror The MEDIA_URL and STATIC_URL settings must have different values
MediaとStaticは別々のURLでないとダメらしいので、同じようにもう1つS3でゲットしてセットしてみた。
これで、一応通った!!あとは、ちゃんと表示されるかのテスト。
・・・
staticファイルが全く通っていないため、多分、AWSの設定をミスってるぽい。。。 再度以下のサイトを見てやり直してみる。
Using Amazon S3 to Store your Django Site's Static and Media Files | Caktus Group
多分、staticrootの設定が間違ってると思う。
静的ファイルについての設定方法を再度公式ドキュメントで確認してみる。
静的ファイルのデプロイ | Django documentation | Django
サイトと静的ファイルを同じサーバから配信する。静的ファイルをすでにサイトを配信しているのと同じサーバから配信したい場合、配信の手順は次のようになります。 デプロイするサーバにコードを push する。 サーバ側で、 collectstatic を実行することで、すべての静的ファイルを STATIC_ROOT で設定したディレクトリに集める。 STATIC_ROOT に置かれたファイルを STATIC_URL から配信するように、Web サーバの設定を行う。たとえば、Apache と mod_wsgi を使用している場合、Apache と mod_wsgi を使用したファイルの配信 が参考になると思います。
とりあえず、collectstaticすると、static_rootにファイルが集まり、それをstatic_urlから配信するということを再確認。ちなみに、collectstaticは、STATICFILES_DIRSも巡回する。
STATICFILES_STORAGEを設定する。
なんと、STATICFILES_STORAGEを設定し忘れていたことを発見orz 設定して再度pushしてみる。
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
これでどうだ。。。以下のerrorが出てしまったorz
'Check your credentials' % (len(names), str(names))) remote: boto.exception.NoAuthHandlerFound: No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV1Handler'] Check your credentials
dotenvモジュールを入れてみる。
dotenvは、os.environ.get が使えるようにするような感じだと思われる。
import dotenv
これで試してみる。
・・・
ダメだ。ただ、直接パスをかくと通るので、多分、書き方が間違っているぽい .
.envは読み込めない、なぜなら.gitignoreで読み込んでいないから。あくまでこれはlocal用のよう。
なんでこんな基本的なことに気づかなかったんや。。。
こちらのサイトが参考になりました、ありがとうございます!
これで一旦、アップは完了。 ただ、MEDIA_ROOTがうまく機能していないので、以下のサイトを参照に後編では、mediaroot, static_rootを再設定してみる。
Using Amazon S3 to Store your Django Site's Static and Media Files | Caktus Group