Till the last part, we had completed our web application starting from User Authentication to CRUD operations and date filtering. If you have missed any part, you can check out the blog series here. In this part (the final one), we're going to deploy our web app on Heroku.
According to Heroku-
Heroku is a cloud platform that lets companies build, deliver, monitor and scale apps — we're the fastest way to go from idea to URL, bypassing all those infrastructure headaches.
To deploy our app on Heroku, we need to make a few changes to our project. But first, you should create a free account on Heroku. Head over to heroku.com and create an account. Once you have created the account, you're ready to proceed.
Set up a Heroku app
Login to your Heroku account, and you'll be welcomed with a similar screen. Ignore the pywisher app.
Click on the New button and then click on Create new app. Enter the app name and then click on the Create app button. Make sure the name is available.
Click on the Settings tab, and scroll down to Buildpacks. Click on the Add buildpack button and add Python.
Since we'll require a database for this application, we are going to add a Postgres database (available for free on Heroku) in the resources. Click on the Resources tab and search for Postgres in the search box. Select Heroku Postgres in the search results, and then click on Submit order form to add it to the resources.
If you remember in the first part where we had set up our project, we had created some environment variables. We need to add them on Heroku too, as without them our app won't work at all. Click on the Settings tab and scroll to Config Vars and click on Reveal Config Vars. Open your
.env file in the project and copy and paste it into your Config Vars as below:
Notice that we have set
True for now, so that we can fix any bug we encounter during deployment. We'll change it to
Set up Github Repository
We'll be deploying our application using Github, which will make our task easier. If you don't have a Github account, create one for yourself here. If you have a Github account, log in to your account. Once you login, you'll see a similar screen:
Click on the New button to create a new repository. Enter the repository name and click on Create repository. Once you create the repository, you'll be on a similar page:
Go to your project on your system. Make sure you have Git installed in your system. If not, install it from here. Open a terminal in your project and write the below commands:
$ git init $ git remote add origin <your-repository-url-here> $ git add . $ git commit -m "Initial commit" $ git push origin master
<your-repository-url-here> with the URL provided by Github. See the image below for reference:
Once you run the above commands, reload the page. You'll see a similar output.
Make changes to the project
First of all, we need to install a few dependencies in our virtual environment. Make sure you have activated it.
$ pip install gunicorn dj-database-url whitenoise psycopg2
- Gunicorn is a Python WSGI HTTP Server for UNIX
- dj-database-url will be used for getting database URL from the Heroku config vars.
- whitenoise is used to serve static files
- pyscopg2 is used for the Postgres database
Once you have installed the above dependencies, add them to a
requirements.txt file. We can generate it automatically using the command:
$ pip freeze > requirements.txt
Next, create a
runtime.txt file and add your Python version there as:
Also, create a
.gitignore file and add the following content:
# Django # *.log *.pot *.pyc __pycache__ media db.sqlite3 # Backup files # *.bak # If you are using PyCharm # .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/gradle.xml .idea/**/libraries *.iws /out/ # Python # *.py[cod] *$py.class # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache .pytest_cache/ nosetests.xml coverage.xml *.cover .hypothesis/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery celerybeat-schedule.* # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # mkdocs documentation /site # mypy .mypy_cache/ # Sublime Text # *.tmlanguage.cache *.tmPreferences.cache *.stTheme.cache *.sublime-workspace *.sublime-project # sftp configuration file sftp-config.json # Package control specific files Package Control.last-run Control.ca-list Control.ca-bundle Control.system-ca-bundle GitHub.sublime-settings # Visual Studio Code # .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json .history
This tells Git to ignore these files.
Go to the Settings tab on Heroku and grab your Heroku app URL from here:
slash(/) from the URL. For example, my URL is:
https://grocery-bag-ashutosh.herokuapp.com/. After the change, my URL looks like this:
GroceryBag/settings.py file and add this URL in the
ALLOWED_HOSTS list as:
DEBUG = config('DEBUG', default=False, cast=bool) ALLOWED_HOSTS = ['127.0.0.1', 'localhost', 'grocery-bag-ashutosh.herokuapp.com']
Add the Whitenoise middleware to the
MIDDLEWARE list as:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # Add Whitenoise middleware here 'whitenoise.middleware.WhiteNoiseMiddleware', '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', ]
Notice that the whitenoise middleware have been included right after the
Next, update the database configurations right after the
DATABASES dictionary as:
import dj_database_url db_from_env = dj_database_url.config(conn_max_age=500) DATABASES['default'].update(db_from_env)
Also, update the STATIC_ROOT as:
STATIC_URL = '/static/' STATIC_ROOT = BASE_DIR / 'staticfiles' # Add this line STATICFILES_DIRS = [ BASE_DIR / "static", ]
Create a Procfile in the root directory of the application and add the following line:
web: gunicorn GroceryBag.wsgi --log-file -
This declares a single process type,
web, and the command needed to run it. The name
web is important here. It declares that this process type will be attached to the HTTP routing stack of Heroku, and receive web traffic when deployed. Notice that the Procfile file doesn't have any extension.
Now, we have done enough changes and we are ready to commit and push it to the Github repository using the commands:
$ git add . $ git commit -m "Ready for deployment" $ git push origin master
Deploy on Heroku
Now we're completely ready to deploy our app on Heroku. Open the Heroku app and click on the Deploy tab. In the Deployment method on the page, choose Github. Search for your repository and click on Connect to select it.
Once it is connected successfully, you'll see a button called Deploy branch. Click on the button and the deployment process will start:
Heroku will install all the dependencies mentioned in the requirements.txt file and will use the Python version mentioned in the runtime.txt file. After the process is completed, you will see a success message as this:
Our app has been deployed successfully!!
But there's one step still left. If you remember, whenever we made any changes to the database, we needed to migrate the database. Similarly here also, we need to migrate the database. Click on More and then on Run Console to run bash:
Once you click on that, you'll find a text box. Write the below command there:
Once you run the command, you'll see the database migrations happening. With this, your app has been deployed successfully and you're ready to test it!
Testing our app
Click on Open app button to view the app:
This was the final blog in this series where we have successfully deployed our app. Definitely, this is not the only way you can create a Todo application, but this is one! Instead of simple HTML forms, we could use Django forms. Instead of Function-based views, we could have used Class-based views. You can modify the code further with the help of Django official documentation.
You can find all the blogs in this series: https://iread.ga/series/11/grocery-bag-application-using-django
Github repository: https://github.com/ashutoshkrris/Grocery-Bag
Deployed App Link: https://grocery-bag-ashutosh.herokuapp.com/
If you have any questions, feel free to comment below!