An in-depth guide on deploying your Discord.js bot on Heroku
Tip: This guide also applies to any Node.js libraries for the Discord API, such as discord.io, eris, and discordie.
Heroku is a cloud platform that offers services to host and deploy your web applications in multiple languages, such as Node.js, Ruby, Python, Java, PHP, and Go.
It's optimal for hosting a bot for several reasons:
-
Free — Heroku offers a free hosting plan, so you don't have to pay at all!
If you plan on using the free hosting plan, you should note the following limitations:
- Limit of 550 hours per month across the applications on your account.
This means that once your apps have been deployed on Heroku for over 550 hours, they will go to sleep, and you can't restart them until the start of the next month when your hours are received.
Luckily, Heroku bumps the limit to 1000 hours per month if you verify your account by adding a credit card to your account, so this limitation won't matter if you do so.
To help colliding with this limitation, I also recommend creating a separate Heroku account for hosting your bot so your other applications don't take up its hosting time.
- Apps sleep after 30 minutes of inactivity; this limitation can be easily bypassed by hosting a web application alongside your bot with Express, and doing so means you also get a website to advertise your bot on. Pretty cool, right?
-
Easily deployable — You can configure Heroku in two ways that allow you to easily deploy any changes made to your bot:
-
Heroku CLI — With the power of Git,
git push heroku master
is all you'll ever need to do with Heroku's easy-to-use command line interface. -
Integrate your app with GitHub for automatic deployment of your bot whenever your configured GitHub repository is updated.
-
-
Online and command line interface — If you're not comfortable with using your command line interface, you can access your app through Heroku's web interface, and vice versa.
A lot of people have run into difficulties while trying to set up their bot on Heroku, however. This guide was created to help resolve some of those issues.
Some additional notes that you should keep in mind as you follow this guide:
-
In the directions throughout this guide,
$
denotes a Bash prompt and should not be included while entering commands in the command line prompt. -
The main script of the bot will be referred to as
index.js
. -
This guide is primarily uses the Heroku CLI (rather than the web interface) to interact with Heroku.
This repository also contains several example files mentioned in this guide for you to use as references, including:
-
package.json
(link) -
Procfile
(link) -
.gitignore
(link) -
index.js
(link)This file contains the source code for the Discord.js Heroku bot on my bot testing server, which serves as a demo of the instructions in this guide; it utilizes Heroku's environment variables.
I'm active member of the Discord.js community on Discord and also a freelance bot developer, so if you're interested in a personal, customized Discord bot, message me on Discord at synicalsyntax#9944 for further discussion.
Before you get started, make sure you have:
-
installed Node (version >= v4.0.0) and npm (you better have, also how would you even know that your bot works? )
-
installed and configured Git on your local machine
-
created a GitHub account and repository, if you're planning on automatically deploying your bot from GitHub
-
installed the Heroku CLI
-
changed your directory path to the root directory of your bot (the one where your bot's files and scripts are located in):
$ cd path/to/directory
In order for Heroku to deploy your bot, you need a file called package.json
that tells Heroku what dependencies to install to run your app.
If you haven't created one already, you can run npm init
in the root directory
of your bot to have an interactive prompt-based setup of your package.json
file.
The process should look like this (you push the Enter
/Return
key to save
your answer and move on to the next prompt):
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (discord.js-heroku)
version: (1.0.0)
description: An in-depth guide on deploying your Discord.js bot on Heroku
entry point: (index.js)
test command:
git repository: https://github.com/synicalsyntax/discord.js-heroku
keywords: heroku, discord.js
author: synicalsyntax
license: (ISC) MIT
About to write to /Users/synicalsyntax/discord.js-heroku/package.json:
{
"name": "discord.js-heroku",
"version": "1.0.0",
"description": "An in-depth guide on deploying your Discord.js bot on Heroku",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/synicalsyntax/discord.js-heroku.git"
},
"keywords": [
"heroku",
"discord.js"
],
"author": "synicalsyntax",
"license": "MIT",
"bugs": {
"url": "https://github.com/synicalsyntax/discord.js-heroku/issues"
},
"homepage": "https://github.com/synicalsyntax/discord.js-heroku#readme"
}
Is this ok? (yes)
Running npm init
won't tell specify your bot's dependencies in package.json
,
but you can do so by running
$ npm install <pkg> --save
This command will install the dependency with the name <pkg>
in the
node_modules
folder while automatically adding the dependency to
package.json
. For example, $ npm install discord.js --save
will install and
add the discord.js
dependency to package.json
.
You'll need to do this for all the dependencies that your bot uses, since
missing dependencies in your package.json
file will cause problems when you
try to deploy to Heroku; packages installed on your system won't be installed on
Heroku unless you specify them in package.json
.
You need to define the version of Node.js and npm that will be used to run your
application on Heroku in your package.json
file. You should always specify a
Node version that matches the runtime you’re developing and testing with.
To find your version of Node, run:
$ node -v
To find you version of npm, run:
$ npm -v
You can now add these versions to your package.json
file like in the example below:
"engines": {
"node": "7.8.0",
"npm": "4.2.0"
},
Your package.json
file should now look something like:
{
"name": "discord.js-heroku",
"version": "1.0.0",
"description": "An in-depth guide on deploying your Discord.js bot on Heroku",
"main": "index.js",
"engines": {
"node": "7.8.0",
"npm": "4.2.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/synicalsyntax/discord.js-heroku.git"
},
"keywords": [
"heroku",
"discord.js"
],
"author": "synicalsyntax",
"license": "MIT",
"bugs": {
"url": "https://github.com/synicalsyntax/discord.js-heroku/issues"
},
"homepage": "https://github.com/synicalsyntax/discord.js-heroku#readme"
}
What's the command that you enter in your command line interface to start your
bot? If your bot's main scripts are located in index.js
, chances are that
command is $ node index.js
. That command will also serve as the start script,
which is what Heroku will run when it tries to start your bot.
To specify the start command, you need to add it to your package.json
file
under the scripts
field, like the example below:
{
"name": "discord.js-heroku",
"version": "1.0.0",
"description": "An in-depth guide on deploying your Discord.js bot on Heroku",
"main": "index.js",
"engines": {
"node": "7.8.0",
"npm": "4.2.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/synicalsyntax/discord.js-heroku.git"
},
"keywords": [
"heroku",
"discord.js"
],
"author": "synicalsyntax",
"license": "MIT",
"bugs": {
"url": "https://github.com/synicalsyntax/discord.js-heroku/issues"
},
"homepage": "https://github.com/synicalsyntax/discord.js-heroku#readme"
}
By default, Heroku looks for a Procfile to determine what processes are run by the dynos (or containers) of your app.
You need to create a file named Procfile
at the root directory of your
application with the following contents:
web: npm start
You should exclude some files from being checked in to Git/version control by
specifying them in a .gitignore
file. One example of files that should be
excluded are those in the node_modules
folder; not doing so results in a build
process that takes forever because the build cache isn't be utilized.
Download this Node .gitignore
template from
your buddies at GitHub and include it in the root directory of your bot.
If you haven't done so already, sign up for a Heroku account and verify it.
To create a new Heroku application, login with your Heroku account credentials when you run:
$ heroku login
Now create an app with name your-app-name
by running:
$ heroku create your-app-name
If your-app-name
is available, Heroku will create an app under that name; once
you set up a web app, you can visit your app's webpage at
https://your-app-name.herokuapp.com
.
Finally, add a Git remote named heroku
pointing to Heroku:
$ git remote add heroku https://git.heroku.com/your-app-name.git
$ git remote -v
heroku https://git.heroku.com/your-app-name.git (fetch)
heroku https://git.heroku.com/your-app-name.git (push)
Note: This step is required if you plan on automatically deploying your bot every time you push changes to a GitHub repository.
To push new commits and changes to a GitHub repository, you'll need to first add a Git remote by running:
$ git remote add origin https://github.com/your-username/your-repo-name.git
If your remote was added successfully, running $ git remote -v
should give you
the following output:
git remote -v
origin https://github.com/your-username/your-repo-name.git (fetch)
origin https://github.com/your-username/your-repo-name.git (push)
You can now push commits to your GitHub repository by running:
$ git push origin master
Follow Heroku's guide on integration with GitHub and enable automatic deploys to deploy your bot whenever you push to your GitHub repository.
Note: This step is not required (especially if you haven't downloaded the Heroku CLI), but it's highly recommended.
You should build your application locally to test if you've set up it correctly.
You can do so by running npm install
to install all your dependencies and then
starting your app locally by running:
$ heroku local
The Heroku CLI will now run your app at http://localhost:5000/; if no errors are encountered, you're on the right track!
To dodge Heroku's "sleep after 30 minutes of inactivity" limitation, you can build a web application to run alongside your bot. We'll be using the Express web framework and the EJS template engine to do so.
Install the express
and ejs
dependencies with npm.
$ npm install express --save
$ npm install ejs --save
Check if they were successfully installed by making sure there are express
and
ejs
folders in the node_modules
folder of your bot's root directory as well
as being listed under the dependencies
field in your package.json
file.
You need to modify your index.js
file to host the web app alongside your bot
by including the following content:
const express = require('express');
const app = express();
// set the port of our application
// process.env.PORT lets the port be set by Heroku
const port = process.env.PORT || 5000;
// set the view engine to ejs
app.set('view engine', 'ejs');
// make express look in the `public` directory for assets (css/js/img)
app.use(express.static(__dirname + '/public'));
// set the home page route
app.get('/', (request, response) => {
// ejs render automatically looks in the views folder
response.render('index');
});
app.listen(port, () => {
// will echo 'Our app is running on http://localhost:5000 when run locally'
console.log('Our app is running on http://localhost:' + port);
});
The first file that needs to be created is views/index.ejs
, the home page of
your web app. You can do so by running:
$ mkdir views
$ touch views/index.ejs
Now, open the file in the default text editor by running:
$ open views/index.ejs
What you put in right now doesn't really matter, but if you want to take the time to add meaningful content to your webpage by following this guide on using the EJS template engine with Express. A blank page will work for our purposes.
Tip: You can add some nice styling to your page by including static assets in the
public
folder.
To prevent your dynos from going asleep, we can send GET requests to your page
every 15 minutes or so to keep it active. We can do so by adding a setInterval
function:
// pings server every 15 minutes to prevent dynos from sleeping
setInterval(() => {
http.get('http://your-app-name.herokuapp.com');
}, 900000);
Now your bot will be up 24/7 until your hour limit for the month is reached.
If you're reading this part of the guide, you should have:
-
developed a functioning Discord bot
-
setup your repository for Heroku deployment
-
created a web application to run alongside the bot
You should now test your app locally by running:
$ heroku local
Keep the bot running for an hour, and see if it works consistently and doesn't fall asleep.
If all is well (or you're too lazy to test locally), you should deploy your app to Heroku by running:
$ git push heroku master
If the app is deployed successfully and works consistently for about thre hours, congratulations! You've finished setting up, deploying to, and hosting your bot on Heroku!
If you have some questions/feedback about this guide, you can message me on Discord at synicalsyntax#9944. Hope you enjoyed this guide! :)
-
Free dyno hours — Additional information about Heroku's free plan, including details about automatic dyno sleeping after 30 minutes of inactivity and hour limits.
-
Deploying Node.js apps on Heroku — The official Heroku guide to deploying Node.js applications.
-
Best Practices for Node.js Development — Official tips and tricks from your friends at Heroku for a quick, easy setup of your app.
-
Heroku Node.js Support — More documentation from your friends at Heroku to help you set up your app.
-
How to Deploy a Node.js App to Heroku — The original tutorial on deploying the web application designed to run alongside your Discord.js bot.
Copyright (c) 2017 Cynthia Lin