Deploy a Go RESTful API to Koyeb: An alternative to Heroku

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:

  1. Installation of the Koyeb CLI

  2. Building the Go API

  3. 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

Screenshot 2022-09-05 at 20.41.34.png

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

Screenshot 2022-09-05 at 20.44.05.png

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:

Screenshot 2022-09-06 at 01.01.56.png

Getting started, we create a GitHub repository for this project which we would deploy to:

Screenshot 2022-09-05 at 23.13.04.png

Initialize an empty git repository in the terminal in your working directory, add and commit the files into the initialized repository and commit :

Screenshot 2022-09-05 at 23.27.51.png

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:

Screenshot 2022-09-05 at 23.28.34.png

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:

Screenshot 2022-09-05 at 23.31.11.png

Clicking on the app name go-koyeb-demo gives us more information:

Screenshot 2022-09-05 at 23.31.30.png

We create a service by clicking on the green button labelled "create a service":

Screenshot 2022-09-05 at 23.31.41.png

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:

Screenshot 2022-09-05 at 23.32.22.png

After adding the GitHub repository, add the name of the repository and select the specific branch you want to deploy:

Screenshot 2022-09-05 at 23.34.51.png

Create the secret key for the PORT variable which we had in our .env file:

Screenshot 2022-09-06 at 11.31.40.png

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:

Screenshot 2022-09-05 at 23.36.37.png

I got an error in my logs as Koyeb built the application:

Screenshot 2022-09-06 at 00.09.12.png

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:

buildflags.webp

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:

outcome.webp

Conclusion

We have successfully deployed a Go RESTful API to Koyeb, a great alternative to Heroku. Until next time, happy coding!