π° Setting up a Kubernetes cluster can be a major time investment. Going from zero to deploy will normally involve many steps, requiring you to refer to documentation and several guides β just to get things stood up in a relatively secure way.
β¨ Encore: a new type-safe workflow for infrastructure
In this article, we'll be using Encore's Infrastructure SDK to declaratively define the infrastructure our Go backend needs, and then use Encore to automatically provision our Kubernetes cluster along with other infrastructure, directly in our cloud account.
Your code will be deployable to both GCP and AWS, and Encore will provision your cluster using either GKE or EKS Fargate, depending on which cloud you choose.πββοΈ
If you prefer, you can also deploy using serverless compute instances, without changing a line of code. This is great for setting up test environments that are cheap and easy to run.πΈ
π What's on deck:
- Install Encore
- Create your backend app from a template
- Run locally
- Connect your cloud account
- Deploy to Kubernetes
Don't feel like building right now? Watch the video instead:
How to deploy a Go backend to Kubernetes
π½ Install Encore
Install the Encore CLI to run your local environment:
-
macOS:
brew install encoredev/tap/encore
-
Linux:
curl -L https://encore.dev/install.sh | bash
-
Windows:
iwr https://encore.dev/install.ps1 | iex
π¨ Create your app
To keep things simple as we explain how Encore works, we're going to clone a pre-made app from Encore's template repo. It's a simple monolith implementing a URL shortener. The app has a REST API and a PostgreSQL database.
Install it by running:
encore app create my-app-name --example=url-shortener
π Running locally
To run the application locally, make sure you have Docker installed and running. This is required to run Encore applications with SQL databases.
Then simply run:
encore run
You should see this:
π§ͺ Try the API
Next, call your endpoint:
curl http://localhost:4000/url -d '{"URL": "https://encore.dev"}'
You should see this:
{
"ID": "5cJpBVRp",
"URL": "https://encore.dev"
}
πΉ Open the developer dashboard
While encore run
is running, open http://localhost:9400/ to view Encore's local developer dashboard.
Here you can see API documentation, use the API via an API explorer, and see traces using Encore's built-in distributed tracing.
π§ Take a look a the code
This app is now running locally, without any manual work to set up a local Kubernetes instance, and we're about to deploy it to our cloud account. So how does it work?
Let's take a look at the code.π
package url
import (
"context"
"crypto/rand"
"encoding/base64"
"encore.dev/storage/sqldb"
)
type URL struct {
ID string // short-form URL id
URL string // complete URL, in long form
}
type ShortenParams struct {
URL string // the URL to shorten
}
// Shorten shortens a URL.
//
//encore:api public method=POST path=/url
func Shorten(ctx context.Context, p *ShortenParams) (*URL, error) {
id, err := generateID()
if err != nil {
return nil, err
} else if err := insert(ctx, id, p.URL); err != nil {
return nil, err
}
return &URL{ID: id, URL: p.URL}, nil
}
// Get retrieves the original URL for the id.
//
//encore:api public method=GET path=/url/:id
func Get(ctx context.Context, id string) (*URL, error) {
u := &URL{ID: id}
err := sqldb.QueryRow(ctx, `
SELECT original_url FROM url
WHERE id = $1
`, id).Scan(&u.URL)
return u, err
}
type ListResponse struct {
URLs []*URL
}
// List retrieves all URLs.
//
//encore:api public method=GET path=/url
func List(ctx context.Context) (*ListResponse, error) {
rows, err := sqldb.Query(ctx, `
SELECT id, original_url FROM url
`)
if err != nil {
return nil, err
}
defer rows.Close()
urls := []*URL{}
for rows.Next() {
var u URL
if err := rows.Scan(&u.ID, &u.URL); err != nil {
return nil, err
}
urls = append(urls, &u)
}
if err := rows.Err(); err != nil {
return nil, err
}
return &ListResponse{URLs: urls}, nil
}
// generateID generates a random short ID.
func generateID() (string, error) {
var data [6]byte // 6 bytes of entropy
if _, err := rand.Read(data[:]); err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(data[:]), nil
}
// insert inserts a URL into the database.
func insert(ctx context.Context, id, url string) error {
_, err := sqldb.Exec(ctx, `
INSERT INTO url (id, original_url)
VALUES ($1, $2)
`, id, url)
return err
}
As you can see there's no Kubernetes configuration or other infrastructure config. It's all Go code, and almost only business logic.
We've simply defined an API endpoint by using the //encore:api
annotation and have imported the encore.dev/storage/sqldb
package.
At compile time, Encore parses the code to understand what the infrastructure requirements are to run the application and then generates the boilerplate code necessary.
When running locally, the CLI takes care of setting up local versions of the infrastructure, and in the cloud Encore provisions the cloud services you need based on your configuration options when you create an environment. Now, let's go ahead and do just that!
β οΈ Connect your cloud account
First, we need to connect a cloud account to Encore. Do this by the Cloud Dashboard > (Select your app) > App Settings > Integrations > Connect Cloud.
AWS
If you are using AWS, follow the instructions on the page to create an IAM Role, and then connect the role with Encore.
For your security, make sure to check Require external ID
and specify the external ID provided in the instructions.
GCP
If you are using GCP, follow the instructions on the screen to create a GCP Service Account for your Encore application.
Note: You need to have a GCP Organization account
to be able to create service accounts.
πΌ Create Environment
Once you've connected your account, it's time to create a new environment. Do this by going to the Environments page in Encore's Cloud Dashboard and clicking Create Environment.
From here you can set up your new environment:
- Select Type as
Production
. - Select Deployment Trigger as
Branch Push
and set the branch name to your git default (e.g.main
, or rungit branch
in your app's root folder if you're unsure). - Select the Cloud to use (Select the one you connect your account for).
- Region (Select the one you prefer).
- Compute instance (Select Kubernetes).
-
Process allocation (Select
All processes in one service
).
Then click Create to save your environment.πΎ
Now we're ready to deploy!β¨
π Deploy to Kubernetes
Before pushing the button, remember: Encore will provision a real-live Kubernetes cluster in your account, along with best practices security measures. This means deploying will incur a cost on your account.π€
To deploy your app and create a new Kubernetes cluster, simply run:
$ git add -A .
$ git commit -m 'Initial commit'
$ git push encore
Encore will now build and test your app, provision the needed infrastructure, including a Kubernetes cluster and database cluster, and deploy your application to the cloud.π
After triggering the deployment, you will see a URL where you can view its progress in Encore's Cloud Dashboard.π
It will look something like: https://app.encore.dev/$APP_ID/deploys/...
From there you can also see metrics, traces, and connect your GitHub account.
πNow you have a fully-fledged Go backend running in Kubernetes, well done!
Note: If you want to keep costs in check, you should delete all the resources created if you don't want to keep using your new cluster. This is easy to do from your cloud provider's console.
π° Great job - you're done!
You now have the start of a scalable Go backend running in Kubernetes.
Keep building with these Open Source Encore App Templates.π
If you have questions or want to share your work, join the developers hangout in Encore's community Slack.π
Top comments (0)