LoginSignup
20
29

More than 3 years have passed since last update.

Django + Heroku + AWS S3で画像表示させる方法

Posted at

概要

Djangoアプリで画像をS3に保存し、アプリに表示させる方法を書いてみます。
想定している処理は、①ユーザーが画像投稿②S3に保存③S3からアプリに画像表示です。

なお、環境はPython 3.7.3Django 2.2になります。

1. AWS設定

1-1. AWS登録

S3を使用するのに、AWSアカウントが必要になりますので、お持ちでない方はAWS Signupからご登録ください。

参照:
AWS アカウント作成の流れ
Amazon S3

1-2. バケット作成

①S3を検索してクリック

s3.png

②バケット作成

s3-02.png

③バケット名とリージョンを選択

s3-03.png

④オプションなし

オプションですが、今回は設定しません

s3-04.png

⑤アクセス権限

こちらの項目を外してください、初期設定ではブロックされてしまいます

s3-05.png

⑥内容を確認して作成

s3-06.png

⑦バケット完成

s3-07.png

1-3. CORS設定

①CORSの設定に移動

作成したバケットをクリックし、「アクセス制限」の「CORSの設定」に移動します

s3-08.png

②CORS構成エディターに追加

下記のように追加してください

CORS
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
   <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

参照:
Cross-Origin Resource Sharing (CORS)
Direct to S3 File Uploads in Python | S3 Setup

1-4. IAM設定

①IAMを検索してクリック

a.png

②ユーザーをクリック

b.png

③ユーザー追加をクリック

c.png

④ユーザー名を入力、プログラムによるアクセスをチェック

d.png

⑤アクセス許可

S3を検索し、AmazonS3FullAccessにチェック

e.png

⑥オプションなし

オプションですが、今回は設定しません

f.png

⑦内容を確認して作成

g.png

⑧IAM設定完了

後ほど、アクセスキーIDシークレットアクセスキーを使いますので、画面を閉じないでください

i.png

参照:IAMとは

2. アプリ設定

2-1. インストール

①django-storagesインストール

terminal
$ pip install django-storages

参照:django-storages | Amazon S3

②boto3インストール

terminal
$ pip install boto3

参照:
Boto 3 Documentation
AWS SDK for Python (Boto3)

2-2. settings.py設定

下記のように追加してください

settings.py
    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'your_app_name',
    'storages', #追加
]

    #追加
    AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
    AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
    AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']

    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    S3_URL = 'http://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
    MEDIA_URL = S3_URL

    AWS_S3_FILE_OVERWRITE = False
    AWS_DEFAULT_ACL = None

2-3. 環境変数

Herokuの環境変数を3つ設定します。

①AWS_ACCESS_KEY_ID②AWS_SECRET_ACCESS_KEYは、IAMユーザーを追加した際に表示された、アクセスキーIDシークレットアクセスキーになります。

③AWS_STORAGE_BUCKET_NAMEは作成したバケット名です。

terminal
$ heroku config:set AWS_ACCESS_KEY_ID="ご自身のアクセスキーIDを記入"
$ heroku config:set AWS_SECRET_ACCESS_KEY="ご自身のシークレットアクセスキーを記入"
$ heroku config:set AWS_STORAGE_BUCKET_NAME="ご自身のバケット名を記入"

参照:
Configuration and Config Vars | Heroku
Django Docs | Deployment checklist

2-4. requirements.txt

インストールしたモジュールをrequirements.txtに追加します。

terminal
$ pip freeze > requirements.txt

2-5. local_settings.py設定

もしlocal_settings.pyを使用している場合は、下記を参考にしてください。

ローカル環境ではMEDIA_ROOTで指定したディレクトリから読み込み、HerokuではS3から読み込むことができます。

settings.py
###
省略
###

DEBUG = False

ALLOWED_HOSTS = ['*']

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'your_app_name',
    'storages',
]

###
省略
###

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

try:
    from .local_settings import *
except ImportError:
    pass

if not DEBUG:
    SECRET_KEY = os.environ['SECRET_KEY']

    AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
    AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
    AWS_STORAGE_BUCKET_NAME = os.environ['AWS_STORAGE_BUCKET_NAME']

    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    S3_URL = 'http://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
    MEDIA_URL = S3_URL

    AWS_S3_FILE_OVERWRITE = False
    AWS_DEFAULT_ACL = None

    import django_heroku
    django_heroku.settings(locals())

db_from_env = dj_database_url.config(conn_max_age=600, ssl_require=True)
DATABASES['default'].update(db_from_env)
local_settings.py
import os

SECRET_KEY = 'ご自身のSECRET_KEYを記入'

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

DEBUG = True

最後に

Herokuでのデプロイが曖昧でしたら、下記の記事も参考にしてみてください。

DjangoアプリをHerokuにデプロイする方法

以上

20
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
29