[PYTHON] Django Heroku Deploy 2

Premise

This is a continuation of the previous article "Django Heroku Deploy 1". https://qiita.com/yusuke_mrmt/items/1a3ee727d119617b2d85

Deploy

Now that we have secured the area to deploy the app, we will actually deploy it.

Flow to deployment

Before deploying, you need to set the following items.

  1. Create a configuration file for Heroku
  2. Installation of application server
  3. Install django-heroku 4, database settings
  4. Allowed host settings
  5. Static file settings
  6. Separation of development environment settings and production environment settings

It will be the above. Set in order.

1. Create a configuration file for Heroku

Add the following two files directly under the project directory.
■ Creating runtime.txt runtime.txt is a file that specifies the version of Python used by Heroku. Save the following contents directly under the project directory (the same directory as manage.py).

runtime.txt


python-3.7.3

■ Creating a Procfile A Procfile is a file that describes the commands that are actually executed on Heroku.
Please save with the following contents.
web: gunicorn config.wsgi --log-file -

I'm running a command called gunicorn. gunicorn is a Python application server.

2. Installation of application server

Install it so that you can run gunicorn, which you mentioned earlier in your Procfile as a command to run on Heroku.

$ pipenv install gunicorn

3. Install django-heroku

Install a library called django-heroku that simplifies the process of applying Django settings to Heroku.

$ pipenv install django-heroku

4, database settings

Set up the database for the production environment. Set DATABASES in config / settings.py as follows.

settings.py


...#abridgement

# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

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

#Postscript
import dj_database_url
db_from_env = dj_database_url.config()
DATABASES['default'].update(db_from_env)

...#abridgement

Import the database settings for Heroku with dj_database_url </ code> and Overwriting DATABASES.

5. Allowed host settings

Django whitelists hosts. Set the app name (first unique setting) in ALLOWED_HOSTS in config / settings.py.

settings.py


ALLOWED_HOSTS = ["<Heroku app name>.herokuapp.com"]

If you don't set this, Django's security features will prevent you from accessing your app. ↓ ↓ Example

settings.py


ALLOWED_HOSTS = ["banban-2020.herokuapp.com"]

6. Static file settings

Because I get stuck in the static file settings when deploying Let's add the settings in the static file of config / settings.py as follows.

settings.py


...#abridgement

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') #Postscript
STATIC_URL = '/static/'

#Postscript
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

...#abridgement

Next, create a static directory in the root directory of your project Create an empty file in it with the name .gitkeep </ code>.

・ ・ ・

[Supplement] Reasons for adding .gitkeep </ code> To deliver static files on Heroku I have to create a static directory, Since an empty directory cannot be managed by git, I am creating an empty file called .gitkeep. It doesn't have to be named .gitkeep, If you want to manage such an empty directory with git, It seems that it is customary to name it .gitkeep.

7. Separation of development environment settings and production environment settings

Finally, the contents set so far are separated between the development environment and the production environment. Add the following to the end of config / settings.py.

settings.py


...
...
...#abridgement

DEBUG = False

try:
    from config.local_settings import *
except ImportError:
    pass

if not DEBUG:
    import django_heroku
    django_heroku.settings(locals())

In django_heroku.settings (locals ()), django_heroku will apply the settings for Heroku for you.

Next, create a configuration file for your development environment that you won't deploy to Heroku. Create config / local_settings.py and save it with the following contents.

local_settings.py


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

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

ALLOWED_HOSTS = []

DEBUG = True

Then create a .gitignore file directly under the project (the same directory as manage.py) and create it with the following contents.

.gitignore


staticfiles
config/local_settings.py
db.sqlite3

.gitignore is a file that declares files that git does not manage. The config / local_settings.py described here will not be pushed to Heroku. In other words, it is a setting for the development environment that is not reflected in the production environment.

This is the end of the modification until deployment.

Deploy to Heroku

You can deploy by pushing with git like the following command in the terminal.

.gitignore


$ git add .
$ git commit -m "initial commit"
$ git push heroku master

↓ ↓ Enter the above $ git push heroku master </ code> and if it works, it will be as follows.

.gitignore


$ git push heroku master
Total 0 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Python app detected
remote: -----> Installing python-3.7.3
remote: -----> Installing pip
remote: -----> Installing dependencies with Pipenv 2018.5.18…
remote:        Installing dependencies from Pipfile.lock (8f0d8d)…
remote: -----> Installing SQLite3
remote: -----> $ python manage.py collectstatic --noinput
remote:        120 static files copied to '/tmp/build_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/staticfiles'.
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> (none)
remote:
remote: -----> Compressing...
remote:        Done: 64.9M
remote: -----> Launching...
remote:        Released v1
remote:        https://banban-2020.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/banban-2020.git
 * [new branch]      master -> master

Next, perform migration with the following command in the terminal. The pipenv run python manage.py migrate command that was done in the local environment The image is that it will be done even in a production environment.

.gitignore


$ heroku run python manage.py migrate

Running python manage.py migrate on ⬢ banban-2020... up, run.8064 (Free)
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, banban, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying banban.0001_initial... OK
  Applying banban.0002_card... OK
  Applying sessions.0001_initial... OK

Go to https://Heroku appname.com/appname/ when you're done! !!

Deployment is complete.

I got an error when deploying

3, Error when installing django-heroku </ b> Enter $ pipenv install django-heroku </ code> into your terminal ... I got a very long error statement. There was the following sentence near the end of the error sentence.

.gitignore


ERROR: ERROR: Package installation failed...
  ☤  ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 0/1 — 

The solution

I entered the following command in the terminal.

xcode-select --install
env LDFLAGS="-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib" pipenv install psycopg2
  • Reference article https://stackoverflow.com/questions/39767810/cant-install-psycopg2-package-through-pip-install-is-this-because-of-sierra

Error deploying Heroku </ b> When I enter $ git push heroku master </ code> in the terminal, the following error occurs.

$ git push heroku master

Enumerating objects: 93, done.
Counting objects: 100% (93/93), done.
Delta compression using up to 8 threads
Compressing objects: 100% (82/82), done.
Writing objects: 100% (93/93), 21.51 KiB | 2.39 MiB/s, done.
Total 93 (delta 33), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote:  !     No default language could be detected for this app.
remote: 			HINT: This occurs when Heroku cannot detect the buildpack to use for this application automatically.
remote: 			See https://devcenter.heroku.com/articles/buildpacks
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !	Push rejected to banban-2020.
remote: 
To https://git.heroku.com/banban-2020.git
 ![remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/banban-2020.git'
muramatsuyuusukenoMacBook-Pro:banban muramatsuyuusuke$ git add .
muramatsuyuusukenoMacBook-Pro:banban muramatsuyuusuke$ git commit -m "initial"
On branch master
Your branch is up to date with 'origin/master'.

The solution

It was solved by generating requirements.txt. When I entered the following command in the terminal and pushed to Heroku again, it passed without problems.

pipenv lock -r > requirements.txt

that's all.

Recommended Posts