Categories:

Go Application deployment on Google App engine flexible environment

Google Cloud App Engine is a Platform as a Service product that allows us to deploy apps written in various runtimes, such as:

  • Python
  • PHP
  • Java
  • Ruby
  • Node
  • Go
  • Ruby, etc

App Engine provides us with two options: the Standard Environment and the Flexible Environment.

The Standard environment is a cloud-native option because it has a very fast spin-up engine that creates instances for our traffic in milliseconds.

The Flexible environment, on the other hand, is different due to its container-based environment that relies on Compute Engine VMs. This is important for many use cases as we can customize our server as per our usage and requirement. This can be the installation of custom packages like ImageMagick, MuPDF libraries, or SSH into our server or run our own bash script, etc. We can use any type of runtime to run our app, and the important thing is that our app should respond in the default 8080 port unless we make some changes.

Here is a detailed idea of the difference between them. https://cloud.google.com/appengine/docs/the-appengine-environments

Here we will be deploying a GO application on Flexible Environment on custom runtime rather than Google App Engine default go runtime as it brings up more concerns, unlike the standard one. We will be adding two files one app.yaml and other Docker file


Lets a take simple GO application that uses GIN web framework to render Hello World to our web browser.

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.String(200, "Hello World")
	})
	r.Run()
}

Time to show the world 🤠🤠 . Lets make this say through our App Engine Flexible environment.

app.yaml

runtime: custom
env: flex

This is pretty straightforward, as we are defining our custom image as runtime with a flexible environment. We can add other options for scaling purposes and port settings. Check out here

Now, let create a Docker file that resides into the root directory.

Docker

# FOR GAE Flexible Environment Custom Runtime 
FROM golang:1.14


# Set necessary environmet variables needed for our image
ENV GO111MODULE=on \
    CGO_ENABLED=0 \
    GOOS=linux \
    GOARCH=amd64

# install build essentials
RUN apt-get update && \
    apt-get install -y wget build-essential pkg-config --no-install-recommends

RUN apt-get install -y mupdf mupdf-tools

# Move to working directory /build
WORKDIR /build

# Copy the code into the container
COPY . .

# Copy and download dependency using go mod
RUN go mod download

# Build the application
RUN go build -o main .

# Export necessary port # default GCP App Engine Port
EXPOSE 8080

# Command to run when starting the container
CMD ["/build/main"]

The docker file will contain all the necessary configuration setup that we need to expose the application over 8080. Here 8080 is our default port for GAE.

Also make sure go.mod and go.sum exists on the root directory so that necessary packages get installed on the deployment system

Now from the gcloud CLI set project on which the application is going to be deployed. For gcloud setup/configuration check this.

 gcloud app deploy

After successful deployment, there will be a URL to the application and we have our app successfully deployed on google app engine flexible environment using a custom runtime image.

For more, if we want our application using GORM to connect over Google Cloud SQL, there is some changes to be done.

  • First, Enable the Cloud SQL Admin API in the project
  • Under app.yaml, we have to tell our application to allow secure connection or else the application can connect to database, make changes as following
runtime: custom
env: flex
beta_settings:
  cloud_sql_instances: $INSTANCE_CONNECTION_NAME$

$INSTANCE_CONNECTION_NAME$ is the connection name of our cloud SQL that we can get from its instance detail.

Like before deploy application.

gcloud app deploy

As the flexible environment, there are many configurations that can be implemented to actually make our system like we want to make and behave as we intend to.