Django Quick Setup Guide with GitLab and Heroku
Ignatius Bagussuputra #tutorial#coding#django#heroku#gitlabCreate Django app and automatically build and deploy to Heroku
Article Index
Heroku is a cloud platform for a developer to deploy their apps and express their idea and design straight to URL. It offers multiple plans, but usually the free tier is more than enough for experimenting or personal use.
Outline & Focus
- Create a virtual environment in Python
- Start a Django project
- Create a Django app and add it to your project
- Deploy your Django app to Heroku
PART A • GitLab and Heroku
-
create a new git repository and new heroku app
-
go to your GitLab repository CI/CD settings and add these to your variables
Variable Value HEROKU_APIKEY [your_apikey] HEROKU_APPNAME [your_appname] HEROKU_APP_HOST [your_webapp] -
initialize git in your project root directory
git init
-
set remote origin to your GitLab repository
git remote add origin https://gitlab.com/username/git-repo-name.git
-
set remote heroku to your Heroku app
heroku git:remote -a heroku-appname
-
configure your
.gitlab-ci.yml
to activate GitLab pipelines -
create a deployment.sh file
deployment.sh #!/bin/bash
python manage.py makemigrations
python manage.py migrate
-
create Procfile to specify executed commands by Heroku app
Procfile migrate: bash deployment.sh
web: gunicorn your_project_name.wsgi
Note - Procfile without an extension, is an essential file for your Heroku app and must be placed in the app’s root directory to explicitly declare a process type from a variety you can choose from. For more information, visit Heroku’s article about Procfile
-
get your .gitignore file before you commit anything
PART B • Python Virtual Environment
We use Virtual Environment to avoid filling our base Python installation with a bunch of libraries we might use for only one project. Some projects might need different versions of the same libraries too, you couldn’t possibly install every version of each dependencies, remember what they’re for, and hope to always avoid conflicts, right?
Another reason to use this is so that other people could recreate the exact environment for your project if you’re going to share it, look for bugs, and all sorts of stuff.
-
Install Python (I recommend Python3)
-
If you’ve installed Python before, make sure you add it to your PATH
-
Install virtualenv using pip
pip install virtualenv
-
Install virtualenv using pip
pip install virtualenvwrapper-win
-
create the your virtual environment
mkvirtualenv your-env-name
Note - To activate your env, use workon your-env-name. To see your envs, use workon
-
Create a text file called requirements and copy all dependencies in the code block below
requirements.txt astroid==2.0.4
autopep8==1.4.2
certifi==2018.8.24
chardet==3.0.4
colorama==0.3.9
coverage==4.4.1
dj-database-url==0.4.2
Django==2.1.1
django-environ==0.4.4
gunicorn==19.7.1
idna==2.6
isort==4.2.15
lazy-object-proxy==1.3.1
mccabe==0.6.1
mock==2.0.0
pbr==5.1.1
psycopg2==2.7.5
pycodestyle==2.4.0
pylint==2.1.1
pytz==2017.2
requests==2.18.4
six==1.10.0
typed-ast==1.1.0
urllib3==1.22
whitenoise==3.3.0
wrapt==1.10.11
-
Make sure you’re working in your virtualenv and install the dependencies from
requirements.txt
pip install -r requirements.txt
Tip - If you get an error saying, for example psycopg2 can’t be installed, remove it from the text file, install from the text file again, and install psycopg2 manually with
pip install psycopg2
and then runpip freeze > requirements.txt
to update therequirements.txt
PART C • Django Project
-
create new project using command
django-admin startproject your_project_name
-
create new app using command inside your project directory
django-admin startapp your_app_name
-
Add and modify these lines in your project’s settings file
project/settings.py import os
import dj_database_url
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PRODUCTION = os.environ.get('DATABASE_URL') is not None
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
...
'your_app_name',
]
MIDDLEWARE = [
...
'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',
],
},
},
]
- 2 & 8 → for Production in Heroku
- 12 → registering your app to the project
- 17 → to use the WhiteNoiseMiddleware
- 23 → to set the global template in your root directory
project/settings.py#92 # If Using Heroku Environment, then Use Database Setting on Heroku
if PRODUCTION:
DATABASES['default'] = dj_database_url.config()
- Set Database to Heroku’s
project/settings.py#130 PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'assets')
]
STATIC_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
- 130 → Add the project root directory
- 135-137 → Set your static files such as CSS, JS, and images inside the
assets
directory
-
Add the path to your app in your project’s urls file
project/urls.py from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app_name.urls')),
...
]
- 2 → Import include and path for urlpatterns
- 6 → Direct path to include your app’s urls file, which you’re going to make
Note - We are trying to build a scalable website and that is why we’re giving the url to our app’s urls file. If we instead give the paths to all of our templates into the main url file, it would get crowded quickly and become hard to maintain
-
modify these files in your apps
project/urls.py from django.urls import path
from .views import *
urlpatterns = [
path('', home, name='home'),
]
project/views.py from django.shortcuts import render
def called_name(request):
return render(request, 'your_template.html')
-
create a
templates
directory inside your app directory and fill it with your html files
See something to improve or fix? In the spirit of open-source, you can create a new issue or contribute directly to this article by sending a Pull Request on GitHub!