Deploy a Go RESTful API to Koyeb: An alternative to Heroku
Streamline Deployment: Go RESTful API on Koyeb, Your Heroku Alternative
After receiving a contract a few weeks ago, my team and I opted to utilize Heroku as our API deployment platform since it offered a free plan that we could begin with before expanding. The team agreed that a free plan would suffice for the time being. I was so pleased about it that I wrote an article about it.
We began working on the system by constructing the backend architecture, designing the system's layout (front-end), and beginning construction.
We deployed the API to Heroku about a week or two ago so the front-end team could integrate. We opted for a break as the parts began to fit together owing to the intense grinding. Heroku unexpectedly surprised us with a great email which stated:
** In order to focus our resources on delivering mission-critical capabilities for customers, we will be phasing out our free plan for Heroku Dynos, free plan for Heroku Postgres, and free plan for Heroku Data for Redis®, as well as deleting inactive accounts **.
I was a little surprised by the Heroku team's choice, but I couldn't dispute it with them. I informed my team colleagues, and we began searching for alternatives in case the job took longer than projected.
While scrolling through Twitter, I came across a tweet promoting Koyeb, a "developer-friendly serverless platform for worldwide app deployment." The blog listed reasons to transition away from Heroku, such as the cancellation of Heroku's free tier. Koyeb's website offers excellent documentation, a well-articulated tutorials page, and a price section that includes a Tailor-made plan. : a deployment option, Koyeb provides us with access to strong components such as:
native autoscaling
automatic HTTPS (SSL)
two (2) free services to deploy our apps
a free $5 monthly credit for any container size up to 2GB of RAM and 100GB of bandwidth. This is equivalent to a nano instance(with 256 MB, 1 vCPU, and 2.5GB SSD each) for 1388 hours or a micro instance (with 512 MB, 1 vCPU, and 5GB SSD)
Looking through the Tutorials portion of the webpage, I observed only information about installing Gin, not a Go API without a web framework (in which our API was developed). So I carried out an experiment to see whether I could deploy our API and because it was a success, I decided to write this post.
This guide will explain how to deploy a Go RESTful API to Koyeb, an alternative to Heroku.
Requirements
The Go programming language installed
A Koyeb account to deploy and run the Go web API
an active GitHub account
The finished project and the live project can be found on GitHub and live.
Steps
To finish this guide and install the Go API on Koyeb, we would be doing the following:
Installation of the Koyeb CLI
Building the Go API
Deployment of the API on Koyeb
Installation of the Koyeb CLI
First of all, we need to create an account. Koyeb has clear and concise documentation for further enquires.
Before we proceed, we need to create an API access token. Go to your accounts page and create one. Store the generated token, as it will be used to log in.
To install the Koyeb CLI, there are different installation guides for different Operating Systems. I have a Mac and will be utilizing Homebrew:
brew install koyeb/tap/koyeb
brew upgrade koyeb
After successfully installing the CLI, log in by running the command and entering the API credential we created earlier:
koyeb login
The login is successful! The next step is to create an app to deploy. This can be done on the Koyeb dashboard, but I will be doing it from the CLI.
Run the command koyeb app init <name-of-your-app>
:
koyeb app init go-koyeb-demo
This creates a new app in our dashboard. To get more information on the created app, we run the command koyeb app describe <name-of-your-app
:
koyeb app describe go-koyeb-demo
For more commands on the CLI, visit the reference tab.
Building the Go API
We start by creating a folder named go-koyeb-demo
in our $GOPATH directory:
mkdir $GOPATH/src/go-koyeb-demo
cd $GOPATH/src/go-koyeb-demo
You can name the folder whatever you want.
Next, we create a go.mod
file to manage our dependencies by running go mod init <project-name>
:
go mod init go-koyeb/go-koyeb-demo
We would be using the chi router for this project. Getting the chi router, we run this command in our terminal:
go get github.com/go-chi/chi
The above dependency (chi package) will be added to our go.mod file.
We create our main.go
and insert the following code content inside:
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"github.com/go-chi/chi"
"github.com/joho/godotenv"
)
// home handler is unexported due to no other package requiring the handler
func home(w http.ResponseWriter, r *http.Request) {
response := "Home page"
json.NewEncoder(w).Encode(response)
}
// loadEnv loads our .env file: we will use this to test locally
func loadEnv() {
err := godotenv.Load()
if err != nil {
log.Fatal("Unable to load env file")
}
}
func main() {
// load our env: to be commented out when we push live
// loadEnv()
// get PORT number from our environmental variable
var portNumber = os.Getenv("PORT")
portNumber = ":" + portNumber
// create a new router
router := chi.NewRouter()
router.HandleFunc("/", home)
// create our server
srv := &http.Server{
Addr: portNumber,
Handler: router,
}
fmt.Printf("Starting server on port %s\n", portNumber)
err := srv.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}
The code above creates a handler named home
which is accessed by /
and displays: "This is the Home Page"
In our code, we are using the os
package to get an environmental variable named "PORT". For the os
package to find it, we need to create a .env file and add the following line:
PORT=9900
We can give the PORT variable any value, but avoid values such as 80, 3306, 5432 and other config values (databases and other configs).
To make sure any missing package (in this case: godotenv package) needed by our project is installed, run:
go mod tidy
Ensuring our app is ready, we can start the server locally by running go run main.go
, and navigating to our browser at http://localhost:9900 which shows "this is the home page".
Deployment of the API on Koyeb
To deploy on Koyeb, there are two primary ways:
GitHub
Docker
The GitHub method will be applied in this article. Just before we create the GitHub repository, we need to create a .gitignore
file that will prevent us from pushing our .env
file (which stores secret credentials such as passwords and tokens) to GitHub:
Getting started, we create a GitHub repository for this project which we would deploy to:
Initialize an empty git repository in the terminal in your working directory, add and commit the files into the initialized repository and commit :
Checkout to a new branch (in this case main
), add the remote GitHub repository to the project and push to the remote version of the local branch:
The Koyeb website gives us the privilege of integrating our GitHub repository into our created app. Go to the website and log in to your account. On the dashboard, you will see the app we created:
Clicking on the app name go-koyeb-demo
gives us more information:
We create a service by clicking on the green button labelled "create a service":
Install the GitHub repository we created by clicking on the install GitHub App
button. This action asks for our GitHub permissions. Select the repository and click on install:
After adding the GitHub repository, add the name of the repository and select the specific branch you want to deploy:
Create the secret key for the PORT variable which we had in our .env file:
Because this is our first app (we have two free services every month), we can create our service without being charged. Give the service a name and create the service:
I got an error in my logs as Koyeb built the application:
Checking the Go documentation using the buildvcs
tag as a search keyword, and looking at this Go issue comment, it seems the error is from the Go version 1.18. The solution is to deactivate the GOFLAGS
environmental variable by setting buildvcs=false
:
By updating the environmental variables (scroll down for the update service
button), Koyeb automatically redeploys my changes and we can see the logs and our app are both successful:
Conclusion
We have successfully deployed a Go RESTful API to Koyeb, a great alternative to Heroku. Until next time, happy coding!