Repository navigation
Deploy to Heroku
Now that we have a great, database-driven app, it's time to deploy it and show it to the world!
We're using the Heroku platform to host it, since the deploy process is very straightforward and effortless.
First of all, we should adapt the back-end server to receive the react-router routes and direct
them to index.html where they belong. We'll also use a directory called build as the app root
for reasons that will be shown later through this step.
nano server.js...
const path = require('path');
...
app.use(express.static(path.resolve(__dirname, 'build')));
...
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'build', 'index.html'));
});The * route will accept anything that's not the routes already declared and must be the last
to be declared in the file, otherwise it will just capture anything and the app will break.
With that little adjustment done, it's time to prep the app for deployment.
To install the Heroku Toolbelt, follow the docs on Heroku CLI on how to do it.
Once the toolbelt is installed, try running which heroku on your terminal to see if it's installed
correctly.
$ which heroku
/usr/local/bin/heroku
Log in to your Heroku account by running heroku login.
$ heroku login
Enter your Heroku credentials.
Email: ****@example.com
Password (typing will be hidden): *******
Logged in as ****@example.com
Once logged in, go to your app's root dir and run heroku create.
$ heroku create
Creating app... done, ⬢ quiet-badlands-18267
https://quiet-badlands-18267.herokuapp.com/ | https://git.heroku.com/quiet-badlands-18267.git
If you supply an app name to the create command, i.e. heroku create app-name, Heroku
will create an app with that name and its address will be app-name.herokuapp.com.
Now we have a new Heroku app that's already online, but doesn't have anything running yet.
Before we deploy our app, though, we need to install an add-on called mLab that's going to
host our MongoDB database.
$ heroku addons:create mongolab
Creating mongolab on ⬢ quiet-badlands-18267... free
Welcome to mLab. Your new subscription is being created and will be available shortly. Please consult the mLab Add-on Admin UI to check on its progress.
Created mongolab-corrugated-31009 as MONGODB_URI
Use heroku addons:docs mongolab to view documentation
Notice that MONGODB_URI is already set for our app.
With that done, we now need to add a script to package.json called heroku-postbuild that
Heroku runs after installing and building all dependencies to your app. heroku-postbuild will
run the script that will create a production React App build that won't rely on react-scripts
to run, hence the need to adapt server.js to serve the app itself, too.
nano package.json...
"scripts": {
...
"heroku-postbuild": "react-scripts build"
}
...
Because of having to run react-scripts build during deployment, we will also need to move
react-scripts to production dependencies from devDependencies.
The final package.json should look like this:
{
"name": "react-apz",
"version": "0.1.0",
"private": true,
"devDependencies": {
"concurrently": "^3.1.0",
"dotenv": "^4.0.0"
},
"dependencies": {
"body-parser": "^1.16.0",
"express": "^4.14.1",
"mongodb": "^2.2.22",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-redux": "^5.0.2",
"react-router-dom": "next",
"react-scripts": "0.8.5",
"redux": "^3.6.0",
"redux-thunk": "^2.2.0",
"uuid": "^3.0.1"
},
"scripts": {
"start": "concurrently \"react-scripts start\" \"node server.js\"",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"heroku-postbuild": "react-scripts build"
},
"proxy": "http://localhost:8080"
}
As of the last time this guide was updated (02/10/2017), issues have arisen with using yarn
to build the app's dependencies. Heroku automatically uses yarn upon detecting a yarn.lock
file in your source code. However, inconsistencies have been reported lately and it's highly
likely that your app may fail to build when deploying to Heroku, so, in the meantime, we will
add yarn.lock to a .slugignore file, so Heroku ignores yarn.lock and proceeds to install
the app's dependencies via npm.
echo "yarn.lock" >> .slugignore
git add .
git commit -m "Ignore yarn.lock when deploying to production"Lastly, we need to tell Heroku what it should run to serve the app, namely node server.js.
To do that, we will create a Procfile that will describe the type of process to run (whether
it's a web server, a queue worker etc.) and what the process will run (e.g. the command line).
nano Procfileweb: node server.js
Heroku apps need at least 1 web-type process (or, to use the correct word, dyno) to be able
to serve apps through HTTP(S). In this case, we're telling it to serve our app to the web by
running node server.js.
Now, that we're good to go, commit all of your changes to your Git repo (or, if you haven't
started a Git repo yet, run git init then heroku git:remote, then commit your changes).
After committing all of the changes to your app, run git push heroku master.
git add .
git commit -m "Add Procfile"$ git push heroku master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 343 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
.
.
.
remote: -----> Build succeeded!
remote: -----> Discovering process types
remote: Procfile declares types -> web
remote:
remote: -----> Compressing...
remote: Done: 30.9M
remote: -----> Launching...
remote: Released v7
remote: https://quiet-badlands-18267.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/quiet-badlands-18267.git
7957415..f903b78 master -> master
The app has now been deployed. You can open it by accessing the URL that was generated by
Heroku when you created the app or by running heroku open at the app's root dir.
Here's the app that was created with this guide.
Any issues and questions will be answered at the Issues tab.