将Django项目部署到Heroku上
我想很多人在使用Django创建项目并部署时都遇到过失败的情况,浪费了很多时间。我也是其中之一,每次都在不断尝试和摸索中。我将记录下一些成功的案例作为备忘参考。需要注意的是,由于还可能存在不能成功的情况或安全性问题,请在应用本文内容时自负责任。
将 settings.py 文件修改为适用于生产环境的版本。
设置.py(只提取重要部分的代码)在默认情况下,也就是在本地开发环境中,应该是这样的。如果只是在本地开发环境中运行,只需要对设置进行一些修改,即将应用程序名称添加到INSTALLED_APPS中(假设添加了应用程序)。为了将来在本地环境和生产环境中使用不同的设置,建议将本地环境的设置保存为类似settings_local.py这样的文件名。
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
DEBUG = True
ALLOWED_HOSTS = []
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
# ローカル環境でも、アプリを追加(manage.py startapp <アプリ名>)した場合、
# ここにアプリ名を登録していると思いますが、それはデプロイ後もそのまま維持します。
'test_app',
]
ROOT_URLCONF = 'apps.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
STATIC_URL = '/static/'
要在Heroku上部署並運行,需要對上述本地開發環境的設定文件進行幾處修改。以下是我實際成功將文件部署到Heroku的示例。
可能的關鍵點有三個。第一個是使白噪音可用,第二個是指定模板位置,第三個是靜態文件位置的觀點。
我認為錯誤可能是由於這些方面的設定不正確引起的,建議根據您的環境進行檢查。
from pathlib import Path
import os
import whitenoise
#修正
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
#追加
SETTINGS_PATH = os.path.dirname(os.path.dirname(__file__))
#ここは、最初はTrueでやってみて、エラーが出ないか確認してからFalseに変えるのも一案。
#(Falseにするとエラーがあったときに原因の究明ができない)
DEBUG = False
#デプロイしたホスト名を記載する
ALLOWED_HOSTS = ['abc.fff.com']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#アプリ名はそのまま。もし動かない場合には、'test_app.apps.Test_appConfig'と
#する必要があるかもしれません。
'test_app',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
#WhiteNoiseを追加。SecurytyMiddlewareがその前に入っているのことを確認しましょう。
#settings.pyの頭にimport whitenoiseとしてモジュールをインポートしておく。
'whitenoise.middleware.WhiteNoiseMiddleware',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
#ここがポイント。テンプレートディレクトリをこのような形で明示してやることが必要。
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# データベースは特にいじらなくても、問題なく動きました。HerokuはPostgreSQLに対応している
# ので、そちらに移植するという選択肢もあるかもしれない。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
#ここからがポイント。静的ファイルの扱いは常にトラブルになりがちなので慎重に設定しましょう。
#ここは特に変更する必要なし。
STATIC_URL = '/static/'
#これを新たに追加する必要があります。静的ファイルのルートを指定します。
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
# STATICFILES_DIRSの設定をしているケースもあるようですが、試行錯誤した結果、個人的には
# 不要ではないかと思います。以下はなくても動きました。
# STATICFILES_DIRS = (
# os.path.join(BASE_DIR, 'static'),
#)
#これも追加。Whitenoiseを使うために必要らしい。
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
2. 准备Heroku上环境配置所需的设置文件。
准备三个文件。runtime.txt 是用于 Python 安装的(有人说这个不需要)、Procfile 是在 Heroku 上执行 manage.py runserver 所必需的文件(可能有些描述错误),requirements.txt 是安装模块所需的文件。值得一提的是,我使用的每个文件都会列出。由于 Heroku 对 Python 版本的支持有限,建议查看 Heroku 网站上的版本信息。
python-3.8.10
web: gunicorn quiz.wsgi --log-file -
dj-database-url==0.5.0
Django==2.2.6
django-heroku==0.3.1
gunicorn
psycopg2==2.8.4
pytz==2019.3
sqlparse==0.3.0
whitenoise==4.1.4
3. 上 Heroku 进行部署。
首先,对于第一次在Heroku上部署Python项目的新手,建议浏览一下官方网站上的教程,大致了解一下并掌握一些常规操作。
我认为Heroku账户的创建方法已经在各种网站上介绍过了,所以我会省略在这里。另外,也有一种方法可以链接GitHub,但我只想介绍一个简单的上传方法。如果需要版本管理,可以尝试使用GitHub进行部署。
<(参考)Heroku CLIのインストール(MACの場合)>
$ brew install heroku/brew/heroku
<(参考)アカウント作成後のログイン>
$ heroku login
<(参考)プロジェクト作成 ※任意のプロジェクト名が自動生成されます。
Herokuのウェブサイトから作成しても良いかも。>
$ heroku create
<アプリ名を表示>
$ heroku apps
<Gitと特定のアプリを連携>
$ heroku git:remote -a アプリ名
$ git init
$ git add .
$ git commit -m "initial commit"
$ git push heroku master
<アプリを動かすコマンド>
$ heroku ps:scale web=1
<アプリを開くコマンド>
$ heroku open
<アプリを止めるコマンド>
$ heroku ps:scale web=0
<(参考)マイグレーションと特権管理者の設定>
$ heroku run python manage.py migrate
$ heroku run python manage.py createsuperuser
(参考)关于Collectstatic
在Heroku上,Collectstatic(自动收集静态文件)操作会自动进行,但我经常看到有关出现错误的文章。虽然我没有遇到过错误,但似乎在本地开发环境中执行collectstatic,并在Heroku上禁用此操作也是一种方法。以下是禁用操作的命令:
$ heroku config:set DISABLE_COLLECTSTATIC=1