Docker を使用して Django アプリを Heroku にデプロイしています。Dockerfile に入力するとRUN manage.py collectstatic --noinput
、環境変数に値が設定されていないため失敗しますDJANGO_SECRET_KEY
。これは、ビルド時に構成変数が利用できないためだと理解しています。
collectstatic を release コマンドとして実行すると、エラーなしで動作し、静的ファイルを正常にコピーします。ただし、アプリの URL にアクセスすると、静的ファイルが見つからないため 500 エラーが返されます。これは、release コマンドが一時的なファイルシステム上の dyno として実行され、コピーされたファイルが見つからないためだと考えられます。
ジレンマのようです。Dockerfile に collectstatic を配置すると、使用できる構成変数がないため失敗しますが、リリース コマンドとして配置すると、ビルド フェーズからのファイルの変更のみが保存されるため失敗します。
何をするか?
settings.pyのcollectstatic設定は次のとおりです。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
...
]
...
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'backend.storage.WhiteNoiseStaticFilesStorage'
Dockerファイル
# Pull base image
FROM python:3.7-slim
# Set environment varibles
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
RUN mkdir /code
WORKDIR /code
# Install dependencies
RUN pip install pipenv
COPY Pipfile Pipfile.lock /code/
RUN pipenv install --system
# Copy project
COPY . /code/
## collect static files
RUN mkdir backend/staticfiles
# This fails because DJANGO_SECRET_KEY can't be empty
RUN python manage.py --noinput
ヒロク
build:
docker:
web: Dockerfile
run:
web: gunicorn backend.config.wsgi:application --bind 0.0.0.0:$PORT
ベストアンサー1
Heroku サポートに確認したところ、確かにこれはちょっとジレンマのようです。
解決策はcollectstatic
、ビルド時に実行され、ファイルが保持されるように Dockerfile に配置することでした。
Django の関数を使用してデフォルトの秘密鍵を設定することで、秘密鍵設定変数がない問題を回避しましたget_random_secret_key
。
実行フェーズでは Heroku 構成変数からの秘密キーが使用されるため、実際には毎回秘密キーが変更されるわけではありません。デフォルトはビルド プロセスにのみ適用されます。collectstatic
秘密キーのインデックスは作成されないため、これは問題ありません。
settings.pyで
from django.core.management.utils import get_random_secret_key
...
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', default=get_random_secret_key())