Heroku deployment

Heroku is a great choice for deploying Python applications. It is easy to use and scalability and flexibility are unmatched among hosting services. Heroku provides reliable platform as a service infrastructure with built-in features such as automated deployment, application metrics, and logs that allow developers to easily deploy their apps without any extra overhead or configuration. Additionally, the Heroku platform supports popular databases like PostgreSQL and MongoDB, web servers such as Nginx and Apache and also offers excellent support for popular web development frameworks like Flask and Django. For users who want more specialized resources, custom add-ons can be integrated seamlessly with the core Heroku platform. Heroku’s rich feature set makes it a great option for those looking to quickly deploy Python applications without worrying about uptime or other technical considerations.

To deploy Django Easystart Apps on Heroku, there are several necessary steps that you need to follow to ensure your app is properly deployed. It’s important not to overlook any of these steps, to ensure your app is ready to go.

  • Docker And Docker compose.

  • Create a S3 Bucket on Digital Ocean.

  • Create your App and deploy it on Heroku.

Docker and Docker compose

Docker and Docker Compose provide a powerful platform for developing applications quickly and efficiently. Docker containers allow you to package your application with all its dependencies, so it can be deployed everywhere without worrying about conflicts between versions or system requirements. What’s more, Docker Compose provides an easy way to configure and manage multi-container applications. This makes it simple to deploy your application in multiple environments - from development, to production, and even across different architectures.

Installing Docker and Docker Compose on the customer’s computer is easy; follow these instructions https://docs.docker.com/engine/install/ (Docker) and https://docs.docker.com/compose/install/ (Docker compose) to get started.

Create a S3 Bucket on Digital Ocean

To deploy Django Easystart Apps on Heroku, you need a secure, fast, and easy-to-use platform to host static files and uploaded media because of Heroku’s ephemeral nature. Digital Ocean Spaces is a perfect solution for hosting static files for Django applications. You can quickly deploy your files to a secure cloud environment with little effort, thanks to its simple setup and easy-to-use interface. If you don’t have an account on Digital Ocean, you can create one using this link: https://m.do.co/c/c6e907d3690f

Follow the official documentation to create your bucket for your static files and make sure to check the Enable CDN option:

https://docs.digitalocean.com/products/spaces/how-to/create/

After creating your bucket, set up access via API by following the official documentation at:

https://docs.digitalocean.com/products/spaces/how-to/manage-access/

Note

Take note of the Secret Key during creation as it is only shown once.

After following the above steps, you will end up with the following variables, which you will need in the next steps of this tutorial:

KEY_ID = <Secret Key to access your bucket via API>
SECRET_ACCESS_KEY = <Secret Key to access your bucket via API>
REGION_NAME = <Region where you created you bucket. Eg: nyc3>
BUCKET_NAME = <The bucket name you gave at creation time>
ENDPOINT_URL = <The URL for your bucket>
ENDPOINT_CDN_URL = <The URL of the CDN for your bucket>

Create and Configure your App on Heroku

To begin this tutorial, installing the Heroku CLI is the first step. To do so, you’ll need to follow the platform-specific instructions available on Heroku’s official documentation page – no need to scour the web for additional resources as everything you need can be found there. Visit https://devcenter.heroku.com/articles/heroku-cli and come back when the heroku-cli is properly installed.

To get started, log in to the Heroku platform using the Heroku CLI command – all you have to do is execute the following command and follow the on-screen instructions.

heroku login

To create your app on Heroku, you need to install the manifest plugin in your Heroku-cli installation. Follow the steps below to install the plugin:

heroku update beta
heroku plugins:install @heroku-cli/plugin-manifest

Note

You can access the official documentation about this topic by visiting the following link: https://devcenter.heroku.com/articles/build-docker-images-heroku-yml#creating-your-app-from-setup

To create your app in Heroku and automatically set the stack of the app to container, use the --manifest flag. To do this, follow these steps:

heroku create  my-app-name --manifest

Note 1

Replace my-app-name with the name you want to give to your app.

Note 2

if you are part of a team, you must include the --org org-id argument in the command above, replacing org-id with your organization’s ID.

After creating your app with the manifest flag, you can locate the heroku.yml file in your source root. This file will help you create and configure your application. To build your docker images correctly, you must set the values of the following variables: HEROKU_DEPLOYMENT, AWS_S3_ENDPOINT_CDN_URL, and AWS_STORAGE_BUCKET_NAME. You can modify these variables by referring to the table below:

Variable

Description

HEROKU_DEPLOYMENT

The deployment target for your application, must be True for Heroku deployments.

AWS_S3_ENDPOINT_CDN_URL

The URL of your Digital Ocean S3 endpoint CDN.

AWS_STORAGE_BUCKET_NAME

The name of your Digital Ocean storage bucket.

Here is an example of the heroku.yml file. Please note that your values must differ:

setup:
  addons:
    - plan: heroku-postgresql:mini
    - plan: heroku-redis:mini

build:
  docker:
    web: ./Dockerfile.heroku
  config:
    HEROKU_DEPLOYMENT: True
    AWS_S3_ENDPOINT_CDN_URL: https://django-easystart-app.nyc3.cdn.digitaloceanspaces.com
    AWS_STORAGE_BUCKET_NAME: django-easystart-app

release:
  image: web
  command:
    - ./heroku-deployment.sh

run:
  web: gunicorn easystart.wsgi:application --worker-class gevent --timeout 120 --workers=2
  worker:
    command:
      - /start-celeryworker.sh
    image: web
  beat:
    command:
      - /start-celerybeat.sh
    image: web

In order for you app to build correctly you will need to set the environment variables needed for your docker image. You can set these variables using the UI interface in your Heroku’s dashboard for your app, or do it directly using the heroku-cli. below there’s a table with the variables you will need to complete this step correctly:

Variable

Description

DJANGO_DEBUG

A boolean value that determines whether your application is running in debug mode. Must be False in Production.

SECRET_KEY

A secret key used for securing your application.

DJANGO_ALLOWED_HOSTS

A comma-separated list of allowed hosts.

CSRF_TRUSTED_ORIGINS

A comma-separated list of trusted origins for cross-site request forgery (CSRF) protection.

HEROKU_DEPLOYMENT

A boolean value that indicates whether your application is being deployed to Heroku. This must be set to True for Heroku deployments.

AWS_ACCESS_KEY_ID

The access key ID for your DigitalOcean Spaces account.

AWS_SECRET_ACCESS_KEY

The secret access key for your DigitalOcean Spaces.

AWS_S3_REGION_NAME

The region name of your DigitalOcean Spaces bucket.

AWS_STORAGE_BUCKET_NAME

The name of your DigitalOcean Spaces bucket.

AWS_S3_ENDPOINT_URL

The URL of your DigitalOcean Spaces endpoint URL.

AWS_S3_ENDPOINT_CDN_URL

The URL of your DigitalOcean Spaces CDN.

AWS_DEFAULT_ACL

The default access control list (ACL) for your DigitalOcean Spaces bucket, by default must be public.

AWS_LOCATION

The location of your DigitalOcean Spaces bucket.

To set the secrets for your project, execute the following commands in your terminal, making sure to replace the placeholders with your own values:

heroku config:set DJANGO_DEBUG=False
heroku config:set SECRET_KEY='YOUR VALUE'
heroku config:set DJANGO_ALLOWED_HOSTS=django-easystart-app.herokuapp.com,
heroku config:set CSRF_TRUSTED_ORIGINS=https://django-easystart-app.herokuapp.com,
heroku config:set HEROKU_DEPLOYMENT=True
heroku config:set AWS_ACCESS_KEY_ID=<YOUR VALUE>
heroku config:set AWS_SECRET_ACCESS_KEY=<YOUR VALUE>
heroku config:set AWS_S3_REGION_NAME=<YOUR VALUE>
heroku config:set AWS_STORAGE_BUCKET_NAME=<YOUR VALUE>
heroku config:set AWS_S3_ENDPOINT_URL=https://django-easystart-app.nyc3.digitaloceanspaces.com
heroku config:set AWS_S3_ENDPOINT_CDN_URL=https://django-easystart-app.nyc3.cdn.digitaloceanspaces.com
heroku config:set AWS_DEFAULT_ACL=public-read
heroku config:set AWS_LOCATION=static

Please note that you don’t need to set the DATABASE_URL, REDIS_URL`, and REDIS_TLS_URL environment variables yourself because Heroku will inject them into your app automatically. Additionally, it’s important to note that when your app runs on Heroku, it will use Redis over TLS, which is mandatory.

Here’s a helpful tip: You can generate a secure SECRET_KEY using the following command:

python3 -c "import secrets; print(secrets.token_urlsafe())"

Just execute this command on your terminal, and it will generate a random value for you. Remember to never share or check in your secrets on your git repository.

Also, keep in mind that it’s important to protect sensitive information like secret keys and passwords. It’s best practice to store them securely and not share them with others.

Deploy your App on Heroku

After modifying the values in your heroku.yml file and setting your environment variables as secrets on Heroku, it’s time to check it in your git repository. To do this, follow the steps below in your source code root:

git add heroku.yml
git commit -m "Added my project values for heroku deployment"
git push heroku master

Note

if you are deploying a branch, the way to deploy is the following: git push heroku branch-name:master, replace branch-name with the name of your local branch.

When you push your code to Heroku, your application will be built, and Heroku will run your application using the command configured in the run section of the heroku.yml file. Don’t forget to push your code to your git repository by executing the following commands:

git push origin master

Before you can run your app, you need to turn on the celery worker and celery beat manually in Heroku because they won’t run by default to avoid extra costs. To do this, go to your app’s resources page at https://dashboard.heroku.com/apps/django-easystart-app/resources and you will see a screen like the following:

../_images/Screenshot_2023-02-18_at_15.55.52.png

Click on the edit button and toggle the button to turn on the workers. Keep in mind that you will be charged for the running dynos after you turn them on. Once you have turned them on, your resources page will look like the following picture:

../_images/Screenshot_2023-02-18_at_15.58.35.png

After you have completed these steps successfully, you can open your app by running the following command in your source code root:

heroku open

Tips

How to rebuild your app again if there’s no code changes?

When you set a config var in Heroku, it typically causes your application to be restarted. However, in most situations, there should be no need to redeploy your application after doing this. If you do need to trigger a new deployment, you can add a new empty commit to your git repository and then push to Heroku again. To do this, follow these steps:

git commit --allow-empty -m "Trigger Heroku deploy"
git push heroku master

Note

if you are deploying a branch, the way to deploy is the following: git push heroku branch-name:master, replace branch-name with the name of your local branch.

Restart your dynos

To restart your dynos execute the following command in your terminal:

heroku restart

Run a shell in your container

To execute a terminal in your dyno, you can execute the following command:

heroku run /bin/sh

Launch a python terminal in your django environment

Also you can open directly a python shell with your environment ready to work:

heroku run python manage.py shell_plus

Fix missing —app flag

If you receive the error message below after executing the commands in this tutorial:

 Error: Missing required flag:
›  -a, --app APP  app to run command against
›  See more help with --help

You have two options to fix this error:

Option 1

Pass the --app my-app-name flag to every command. Replace my-app-name with the name of your app. This will ensure that the command is run against the correct app.

Option 2

Set the HEROKU_APP environment variable in your terminal. You can set the HEROKU_APP environment variable in your terminal to avoid having to pass the --app flag to every command. To do this, follow these steps in your terminal:

export HEROKU_APP=my-app-name

Then, verify that the environment variable was set correctly by entering the command echo $HEROKU_APP.

Now you can run all your commands without passing the --app flag.