Deploy Python Flask app to Heroku with Bitbucket Pipelines

Introduction

Building your application is the fun part, but delivering your application is equally important. Many engineers lack the additional devops knowledge or time required to build and maintain a pipeline process using tools like Jenkins, or Bamboo. Bitbucket has saved the day, we’ll explore how.

In this tutorial, we’ll explore the various options and functionality available to help us easily build, test and deploy our Python applications with just a few lines of yml

This post is based on a talk that I’ll deliver at the Little Rock Tech Fest in October. You can download the source from Bitbucket here.

Bitbucket Pipelines Config Options

There are a ton of different options available to you when configuring your pipeline. For the sake fo simplicity and for this blog post, I’ll just breifly go over the options that we’ll use in this app.

  • image The Docker image BitBucket should use when building your app. This can be an image that’s already on Docker hub, or your own image. Either way, it should contain all of the software you’ll need to buil dyour application.
  • pipelines This key contains all of your pipeline definitions.
  • branches Contains the pipeline definition for all branches (that aren’t in other sections)
  • step Defines a build execution unit
  • script The list of commands executed to perform the build

Create a Heroku App

This part is crazy easy. Just login to your Heroku account, click Create App and fill out the form. We don’t need anything else.

For this post, we’ll say the app name is abinaryworld (Replace this with whatever you want to call your app, and make sure you replace it in the environment variables we set below)

Repository Setup

In your BitBucket repository settings, you’ll find a section specific to Pipelines. This is where you’ll enable the funtionality for your repository, add any necessary environment variables, ssh key and known host information, and any desired integrations.

In the Settings section we’ll enable the Pipeline functionality, then add the following envrionment variables in the Environment Variables section.

  • HEROKU_API_KEY: This is the API key from your Heroku Account Settings page. We need this since we are deploying our app to Heroku
  • HEROKU_APP_NAME: Whatever you called your Heroku app when you created it.

Setup the App

This is the fun part! The reason I love the work that BitBucket has done is because it allows us to focus on what we love… coding.

Create App Directory

mkdir abinaryworld

Initialize the virtualenv

We’ll use virtualenv for this post, but you can use any virtual environment you like. I just like virtualenv because it’s easy, and serves it’s purpose. So cd into your project directory and run virtualenv env

This will create the required environment within the env directory so you can activate it with ./env/activate.

Initialize git

If you haven’t already, initialize this new directory as a git repository and add the remote from the repository we just created above.

git init
git remote add origin {whatever}

Also, create a .gitignore file and add env and __pycache__ on separate lines.

The Procfile

The Procfile is Heroku specific. It tells Heroku how to launch our application once it’s deployed. We’ll use gunicorn as our gateway server. Crate a file called Procfile and add the following line to it:

Procfile
web: gunicorn app:app

Install and freeze requirements

For this project, we’ll need to install gunicorn and flask.

pip install gunicorn
pip install flask

After both of those have successfully installed to your virtual environment, freeze the requirements into a requirements.txt file.

pip freeze requirements.txt

The bitbucket-pipelines file

This is where all the magic happens. This file describes to BitBucket how and when the application should be built or deployed.

bitbucket-pipelines.yml

image: python:3.7.0 #This can be any docker image

pipelines:
  branches:
        master:
      - step:
              name: Run tests
                script:
                  - pip install -r requirements.txt
                  - python tests.py

      - step:
        name: Deploy to Heroku
                script:
                  - git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git HEAD

This file tells BitBucket that we only care about changes pushed to the master branch, and that we want to test and deploy everything committed to this branch. You can specify other branches, too. You can even specify a default branch that will trigger anytime a commit is pushed to any branch that is not listed above.

Create The Test

In my world, TDD is everything and helps ensure that our app behaves as we expect. So we’re going to write the test first. We want our app to return a simple text string of Hello, Internet! when we make a GET request to the root.

I’ll use unittest to and write a simplistic test for our Hello, Internet app. Let’s call this tests.py

tests.py

import app
import unittest

class AppTestCase(unittest.TestCase):

    def setUp(self):
            self.app = app.app.test_client()

        def tearDown(self):
            pass

        def test_hello_internet():
            res = self.app.get('/')

                assert res.status_code = 200
                assert res.get_data(as_text=True) == 'Hello, Internet!'

if __name__ == '__main__':
    unittest.main()

This is a simple test that will ensure our app responds to a GET / request with a 200 status code, and the body test of _Hello, Internet!’

Create The App

Now we get to write out simple Flask app.

app.py

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_internet():
    return 'Hello, Internet!'

Wrap Up

That’s literally it! We’ve written a simplistic Flask app, a unit test, and configured a pipeline.

The only thing left is to commit all of these files with git add . and git commit -m 'Hello internet app', then push to the remote: git push -u origin master

This will automatically trigger the pipeline that will build, test and deploy our app to Heroku. You can see the progress/status of the pipeline on the Pipelines page on BitBucket.

After the pipeline completes successfully, visit your new app at http://abinaryworld.herokuapp.com (remember to replace abinaryworld with the app name you chose above.

Conclusion

BitBucket has made a tool that enabled us to focus more on the code, and not worry so much about how our application is developed. This tool is crazy easy to use, and is free with your BitBucket repository.

You can get as complex, or simplistic as you want with your pipelines.

If you’ve found this post interesting, please feel free to share the link and let me know in the comments below 🙂

Your email address will not be published. Required fields are marked *

*