Deploy a React App to Heroku with Bitbucket Pipelines
Tags: react, devops, webdev, tutorial
Published: 2020-08-24 19:44:58

# Deploy a React App to Heroku with Bitbucket pipelines

In preparation of a talk for an [Atlassian Community Event](https://ace.atlassian.com/hamburg/) in Hamburg I struggled and stumbled upon some documentations and tutorials for using Bitbucket and Heroku together. So I’ve decided to write my own first developer article about
> Building a basic CI/CD pipeline for deploying a **React App** to **Heroku** using **Bitbucket**

------

## Getting Started

### Step 1 — Create React app

In this tutorial we will focus on deploying a React app to Heroku, so we will just use the React starter app. To run the App in Heroku we’ll add a basic express server setup later on.

Prerequisite for creating and running a React app make sure you have:

1. [Node.js](https://nodejs.org/en/) and [npm](https://www.npmjs.com/) installed

1. [Visual Studio Code](https://code.visualstudio.com/) installed (optional)

Now with that basic setup we are ready to create our React app:

    npx create-react-app name-of-your-app

Depending on your development environment grap yourself a coffee, the next 2–5 minutes are not that interessting, except you like watching how all the project dependencies are downloaded and bundled together.

After you are back, type the following lines into your terminal to start the app

    cd name-of-your-app
    npm start

You can now view the app in a browser by open the URL [http://localhost:3000](https://localhost:3000)

------

### Step 2 — Create Bitbucket Repository

![](https://cdn-images-1.medium.com/max/2000/1*AcZj0XMWhsJQhbhGYJwaXg.png)

Now that we have our app up and running on our local machine we should create our git repository. Therefore we head over to [https://bitbucket.org](https://bitbucket.org-.). If you don’t have an account yet, get one its for free (important nowadays)!

When creating a new repository you need to at least give it a name and you want to set the access level to private. Most of the settings here can be changed afterwards.

![Create dialog at bitbucket](https://cdn-images-1.medium.com/max/2352/1*tOBzFBAwR7MxPyihGo_xyg.png)

Well done! You’ve created your — maybe first — git repository. Time to explore the menu which you’ll now see on the lefthand side.

![Menu of your bitbucket repository](https://cdn-images-1.medium.com/max/2136/1*Pvvny02RIdvfu0vfnrf3Qw.gif)

If you want to know more about Bitbucket head over to the [official documentation](https://confluence.atlassian.com/bitbucket/bitbucket-cloud-documentation-221448814.html).

------

### Step 3 — Create Heroku App

![](https://cdn-images-1.medium.com/max/3200/1*o92hHoWIi64nX7XYaN1CwQ.png)

We are pretty close to deploying our app now. Head over to [https://heroku.com](https://heroku.com) - again create an account if you don’t have one (IT’S FREE!).

On your dashboard click **New** and choose **Create new app**. In the dialog

1. Set a **App Name** - this one is unique world-wide, so it might happen that some else already picked **test123** or **demoapp** - be creative!

1. Choose the **Region** where your app should run

![Create dialog at heroku](https://cdn-images-1.medium.com/max/2000/1*8FYmS3Ci_hLJJPcEG9nyLA.png)

Your app is now created, but before you head back to your code and git repository we need to tell our app which [Buildpack](https://devcenter.heroku.com/articles/buildpacks) we’d like to use.

1. Go to **Settings** in your App

1. Under **Buildpacks** click **Add buildback** and choose [**heroku/nodejs](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-nodejs)**

![Buildpacks configuration](https://cdn-images-1.medium.com/max/2456/1*hP_1134FuZXN-axt6qKYHw.png)

For deploying the app later on we also need an API Key.

1. In your Profile go to [Account Settings](https://dashboard.heroku.com/account)

1. In the Section **API Key** click **Reveal**

1. Safe the key for later configuration

------

## Deploy with Bitbucket pipelines

Now comes the fun part… for you actually, I learned the hard way so you don’t have to.

### Step 1 — Setup an express Server

Go to Visual Studio Code and add a new folder called **server** to the root of the repository. Within that folder create a file called **server.js** and install express by running this command in your terminal:

    npm install express --save

Within the **server.js** file copy & paste these lines of code:

    const path = require('path');
    const express = require('express');
    const app = express();
    const publicPath = path.join(__dirname, '..', 'build');

    const port = process.env.PORT || 3000;

    app.use(express.static(publicPath));

    app.get('*', (req, res) => {
        res.sendFile(path.join(publicPath, 'index.html'));
    });

    app.listen(port, () => {
        console.log('Hello World I run on PORT ' + port);
    });

![Capture of my vscode](https://cdn-images-1.medium.com/max/2000/1*CknmspYBmkoCp1eWVvOuUw.png)

In your **package.json** file change the script line for start your app to:

    "start": "node server/server.js",

------

### Step 2 — Upload everything to your git repository

Open a terminal windows make sure you are in the root directory of your React app and type the following lines:

    git init
    git add .
    git commit -m "initial commit"
    git remote add origin [https://username@bitbucket.org/username/name-of-your-repository.git](https://username@bitbucket.org/username/name-of-your-repository.git)
    git push -u origin master

When you refresh the browser page you should see all the files and folders of your app we’ve just commited the the git repository.

------

### Step 3 — Setup and configure Bitbucket pipelines

Now that our code is in our repository we need to enable Pipelines for our repository.

1. Go to Repository Settings

1. Under the Section **Pipelines** click **Settings**

1. **Enable Pipelines**

1. Right above Settings, go to **Repository variables**

1. Add a variable with name HEROKU_API_KEY and your key from above

1. Add a variable with name HEROKU_APP_NAME and the app name as value

Now we can finally create our Pipeline configuration.

![[https://i.imgur.com/UhGt0uR.gif](https://i.imgur.com/UhGt0uR.gif)](https://cdn-images-1.medium.com/max/2000/1*dkz6Vib9eZHH9jJI6qAJXg.gif)

In our case we want (not true, the author wants it!) to build a pipeline with following rules and steps:

1. We don’t have branches yet, so everytime someone commits something to the master branch we want to run our pipeline

1. We want to test our app first

1. We need to create a Zip file for the heroku pipline add-on

1. We want to finally push our repository to Heroku
> # Author’s note: YES, I could push the repository to Heroku using git, but NO that was not my intention for writing this article!

The **bitbucket-pipelines.yml** file holds all the build configurations for your repository. There is really a lot you can do with this file, so if you want to dig deeper take a look at the [official documentation](https://confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html). Here the basics of the [YAML](https://yaml.org/) file:

**pipelines**: contains all your pipeline definitions.

**default**: contains the steps that run on every push if one of the following criteria is not met.

**step**: each step starts a new Docker container with a clone of your repository, then runs the contents of your **script **section.

**script**: a list of commands that are executed in sequence.

**pipe**: a pipe is more like an add-on or function, it takes some input and does stuff for you — like uploading your repository to Heroku

Our final **bitbucket-pipelines.yml** file looks like this:

    image: node:10.15.3

    pipelines:
      branches:
        master:
          - step:
              name: Test App
              caches:
                - node
              script:
                - rm -rf package-lock.json
                - rm -rf node_modules
                - npm install
                - npm run test
           - step:
               name: Create artifact
               script: 
                 - git archive --format=tar.gz master -o                   application.tar.gz 
             artifacts: 
               - application.tar.gz
           - step:
               name: Deploy to heroku
               deployment: production
               caches:
                 - node
               script:
                 - pipe: atlassian/heroku-deploy:1.1.4
                   variables:
                     HEROKU_API_KEY: $HEROKU_API_KEY
                     HEROKU_APP_NAME: $HEROKU_APP_NAME
                     ZIP_FILE: "application.tar.gz"
                     WAIT: 'true'

## The END

Hope you liked it, even more I hope it helps you! Please let me know! :)