mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-08 16:06:13 +02:00
Add blog post on deploying Kotlin bots to Heroku
This commit is contained in:
@@ -0,0 +1,238 @@
|
|||||||
|
---
|
||||||
|
authors:
|
||||||
|
- "Chill#4048"
|
||||||
|
created_at: "2020/04/22"
|
||||||
|
title: "Deploying discord bots written in Kotlin to Heroku"
|
||||||
|
external_resources:
|
||||||
|
- "https://devcenter.heroku.com/articles/getting-started-with-java#introduction"
|
||||||
|
- "https://github.com/heroku/java-sample"
|
||||||
|
---
|
||||||
|
|
||||||
|
Over my time in TPH, I have noticed that a common woe aspiring bot developers have is that they are unable to host
|
||||||
|
their Discord bot online as they may not have access to a credit card.
|
||||||
|
|
||||||
|
## Introducing Heroku!
|
||||||
|
|
||||||
|
While the official Discord bots used in TPH - like HotBot - is hosted via paid platforms, there are free alternatives
|
||||||
|
to deploying your bot online. This is where Heroku comes into the picture!
|
||||||
|
|
||||||
|
> Heroku is a cloud platform that lets companies build, deliver, monitor and scale apps — we're the fastest way to
|
||||||
|
> go from idea to URL, bypassing all those infrastructure headaches.
|
||||||
|
|
||||||
|
Heroku's free tier does not require any credit card information and has sufficient uptime for your basic bot
|
||||||
|
development needs and it is a great starting place to understand hosting.
|
||||||
|
|
||||||
|
## How does Heroku work?
|
||||||
|
|
||||||
|
Before diving into setting up a Discord bot on Heroku, it is best to explain how Heroku is used. Heroku relies on the
|
||||||
|
Git version control system (VCS) to manage an application. This means that it integrates well with any existing projects
|
||||||
|
that already use Git. Do not fret, even if your application does not use Git, the configuration and setup for Heroku is
|
||||||
|
still simple.
|
||||||
|
|
||||||
|
By using Git, Heroku receives the project files directly and it is responsible for building the project. This is unlike
|
||||||
|
other hosting platforms where you would often only supply the final executable - a `.jar` file in our case - to the
|
||||||
|
hosting platform to run.
|
||||||
|
|
||||||
|
In order for Heroku to understand how it will build and deploy your application, you must provide a `Procfile`.
|
||||||
|
|
||||||
|
The `Procfile` is comprised of two key components - the dyno to run the application on and the commands to run your
|
||||||
|
application.
|
||||||
|
|
||||||
|
According to the [Heroku documentation on dynos](https://www.heroku.com/dynos), dynos are containers that are used to
|
||||||
|
run and scale all Heroku applications. Rather than worrying about configuring your build environment or OS, you can
|
||||||
|
focus on building your applications and allowing Heroku to take over the build and deployment process. For all
|
||||||
|
Discord bots, we will use a **worker** dyno.
|
||||||
|
|
||||||
|
The build commands we supply correspond to the build commands we use to run our bots locally.
|
||||||
|
|
||||||
|
As Heroku uses the project files to determine the type of tools we are using, we do not need to specify the
|
||||||
|
instructions to create the executable. In our case, since we are using Maven, it can intelligently detect the
|
||||||
|
`pom.xml` file and create the `.jar` accordingly. This leaves us with only the run commands to include in our `Procfile`.
|
||||||
|
|
||||||
|
Finally, to tighten security, we will store all bot tokens in Heroku's
|
||||||
|
[config vars.](https://devcenter.heroku.com/articles/config-vars) From a code perspective, these config vars are simply
|
||||||
|
environment variables available to our applications. This allows us to load our bot token during runtime and prevent
|
||||||
|
the bot token from being leaked.
|
||||||
|
|
||||||
|
Thus, we can define our deployment plan as such:
|
||||||
|
|
||||||
|
1. Initialise the codebase as a Git repository
|
||||||
|
2. Create a Heroku application for the bot
|
||||||
|
3. Create a `Procfile` to supply instructions for Heroku to run the bot
|
||||||
|
4. Store the bot token as a config var to be used by your bot
|
||||||
|
|
||||||
|
What I have just presented is a general overview of Heroku as a hosting platform. I will be diving into the implementation
|
||||||
|
in the following sections.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
For this article, I will be using a very simple Discord bot written in Kotlin. I have chosen to use JDA as the focus of
|
||||||
|
this guide is to understand Heroku. The code repository can be found
|
||||||
|
[here.](https://github.com/woojiahao/discord-heroku-deployment-demo)
|
||||||
|
|
||||||
|
If you wish to follow along, you can get the repository via
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://github.com/woojiahao/discord-heroku-deployment-demo ping-bot
|
||||||
|
$ cd ping-bot/
|
||||||
|
```
|
||||||
|
|
||||||
|
Aside from that, basic understanding of the following is good to have to understand the technical details of this guide.
|
||||||
|
|
||||||
|
1. [Git](https://git-scm.com/book/en/v2) - version control system that integrates with Heroku to enable easy deployments
|
||||||
|
2. [Maven](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) - build tool for Kotlin to
|
||||||
|
manage application dependencies
|
||||||
|
|
||||||
|
In Kotlin/Java, we are looking to create a `.jar` file. This `.jar` file can be thought of like a `.exe` file.
|
||||||
|
Essentially, it bundles the application and allows us to run our bot without having to fire up an IDE.
|
||||||
|
|
||||||
|
To create this `.jar` file, we will use Maven. For more information about using Maven to create `.jar` files, refer to
|
||||||
|
[this](http://tutorials.jenkov.com/maven/maven-build-fat-jar.html) guide.
|
||||||
|
|
||||||
|
With the formalities out of the way, let's get down to deploying our bot.
|
||||||
|
|
||||||
|
## Installing Heroku
|
||||||
|
|
||||||
|
You will have to install Heroku onto your machine to execute the following commands in the command line. You can find
|
||||||
|
the installation instructions for Heroku [here](https://devcenter.heroku.com/articles/heroku-cli).
|
||||||
|
|
||||||
|
To ensure that you have installed Heroku successfully, run `heroku --version`. My version of Heroku is
|
||||||
|
`heroku/7.39.2 linux-x64 node-v13.12.0`
|
||||||
|
|
||||||
|
## Setup a Git repository
|
||||||
|
|
||||||
|
As mentioned earlier, we need to ensure that our application is a Git repository for Heroku to work.
|
||||||
|
|
||||||
|
While it is recommended to [publish your repository to GitHub](https://help.github.com/en/github/importing-your-projects-to-github/adding-an-existing-project-to-github-using-the-command-line) (or any other version control website), it is not necessary
|
||||||
|
for deploying your applicaiton to Heroku.
|
||||||
|
|
||||||
|
If you are using the sample bot, it is already a Git repository.
|
||||||
|
|
||||||
|
If you are deploying your own bot, initialise a repository by using the following command inside the root folder of your
|
||||||
|
codebase.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git init
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create a new Heroku application
|
||||||
|
|
||||||
|
Then, we want to create a Heroku application.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku create [project name]
|
||||||
|
```
|
||||||
|
|
||||||
|
The project name is optional and will be automatically generated if not provided. It is recommended that you give a name
|
||||||
|
to be organised.
|
||||||
|
|
||||||
|
To ensure that the Heroku application has been created, run the `git remote -v` command to list the remotes of your
|
||||||
|
repository. Should your application have been created successfully, you will see a new remote added linking to a Heroku
|
||||||
|
Git remote.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git remote -v
|
||||||
|
heroku https://git.heroku.com/chill-ping-bot.git (fetch)
|
||||||
|
heroku https://git.heroku.com/chill-ping-bot.git (push)
|
||||||
|
```
|
||||||
|
|
||||||
|
With the Heroku application created, we can begin configuring our repository to deploy to Heroku.
|
||||||
|
|
||||||
|
## Creating a Procfile
|
||||||
|
|
||||||
|
As explained earlier, the `Procfile` acts as a build instruction manual for our application. It instructs Heroku how we
|
||||||
|
want to run our application. Heroku takes over the rest and helps with managing our build environment.
|
||||||
|
|
||||||
|
For my sample bot, the `Procfile` looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
worker: java -jar target/Bot.jar
|
||||||
|
```
|
||||||
|
|
||||||
|
Let's breakdown this file. We first declare the dyno type as `worker`. Then, we specify the command to run our `.jar`
|
||||||
|
file.
|
||||||
|
|
||||||
|
Heroku is able to intelligently detect that our Kotlin application uses Maven as a build tool and runs the
|
||||||
|
`mvn clean install` command to create our `Bot.jar` file. Then, it will use the commands in the `Procfile` to run the
|
||||||
|
application.
|
||||||
|
|
||||||
|
## Securing Discord bot tokens
|
||||||
|
|
||||||
|
A Discord bot requires a token to run.
|
||||||
|
|
||||||
|
You can obtain this bot token when you make a new Discord bot from the Discord
|
||||||
|
[developer dashboard](https://discordpy.readthedocs.io/en/latest/discord.html).
|
||||||
|
However, you do not want to expose this token in your repository as this would mean that others could launch and
|
||||||
|
access your bot.
|
||||||
|
|
||||||
|
As mentioned earlier, we will make use of Heroku's [config vars](https://devcenter.heroku.com/articles/config-vars) to
|
||||||
|
safely store and access this token.
|
||||||
|
|
||||||
|
We will add our bot's token as an environment variable and use `System.getenv()` method to retrieve this value.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku config:set BOT_TOKEN=<bot token>
|
||||||
|
```
|
||||||
|
|
||||||
|
Inside the `Bot.kt` file, you will find the following lines in the `main()` function.
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
val token = System.getenv("BOT_TOKEN")
|
||||||
|
?: throw Exception("Must include bot token in environment variable for bot to run")
|
||||||
|
```
|
||||||
|
|
||||||
|
This will retrieve the corresponding environment variable that we have stored in Heroku. If there is no environment
|
||||||
|
variable present, we will stop the bot from launching and display an error.
|
||||||
|
|
||||||
|
An additional benefit of storing our bot tokens as an environment variable is that we are able to store the bot token
|
||||||
|
locally as an environment variable which streamlines our development process as we could have a separate token used
|
||||||
|
for a development/testing bot.
|
||||||
|
|
||||||
|
## Launching the bot
|
||||||
|
|
||||||
|
After configuring everything, commit all the changes to your project, and push it to the `heroku` remote.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git add .
|
||||||
|
$ git commit -am "Setup Heroku"
|
||||||
|
$ git push heroku master
|
||||||
|
```
|
||||||
|
|
||||||
|
If you encounter a problem with pushing to the `heroku` remote, use the command `heroku logs --tail` and find the
|
||||||
|
latest error messages to debug any errors.
|
||||||
|
|
||||||
|
After pushing the changes, Heroku will build your application. However, it is not online yet as you have to scale
|
||||||
|
your application. This tells Heroku how many instances of your application you wish to run. For our case, we can go
|
||||||
|
with one worker dyno.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ heroku ps:scale worker=1
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now invite your bot to a server and test it out. If you're using the sample PingBot, you can use `!ping` and
|
||||||
|
expect the bot to respond with `Pong!`.
|
||||||
|
|
||||||
|
## Now what?
|
||||||
|
|
||||||
|
Congratulations! You have just deployed a Discord bot onto Heroku! When you make changes to the bot, you are free to
|
||||||
|
commit and push those changes to the `heroku` remote to update the bot that is online.
|
||||||
|
|
||||||
|
Here are some tips for developing with Heroku.
|
||||||
|
|
||||||
|
1. While working on your development copy of the bot, it is recommended that you obtain a seprate bot token and
|
||||||
|
attach it as an environment variable to your local development environment. Doing so allows you to maintain your
|
||||||
|
bot's uptime while making changes.
|
||||||
|
2. If you encounter any errors or your bot is not responding, use the `heroku logs --tail` command to view the logs
|
||||||
|
of your application. Doing so allows you to check if there were any errors while running your project.
|
||||||
|
3. If you require persistent storage, Heroku comes with a free tier plugin for
|
||||||
|
[PostgreSQL.](https://www.heroku.com/postgres) Heroku - by default - has ephemeral storage, meaning it does not
|
||||||
|
maintain new files after each build.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
Heroku offers a free alternative to many hosting platforms and is a perfect platform for aspiring bot developers to begin.
|
||||||
|
|
||||||
|
More resources on hosting JVM-based applications on Heroku:
|
||||||
|
- [Getting Started on Heroku with Java](https://devcenter.heroku.com/articles/getting-started-with-java#introduction)
|
||||||
|
- [Java Sample (on GitHub)](https://github.com/heroku/java-sample)
|
||||||
|
|
||||||
Reference in New Issue
Block a user