October 20, 2016 · gcp google app engine docker golang

Deploying to Google App Engine using Docker

This post details how to deploy a Docker service to Google App Engine using App Engine Flexible Environment.

Create an HTTP Server

Let's start by writing a simple Hello World server using Golang in a project called hellogo:

$ mkdir -p $GOPATH/src/github.com/breerly/hellogo
$ cd $GOPATH/src/github.com/breerly/hellogo

Create a main.go with a net/http server that listens on 8080 - the port App Engine uses to route traffic:

package main

import (  
    "fmt"
    "log"
    "net/http"
)

func main() {  
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello Go!")
    })

    log.Fatal(http.ListenAndServe(":8080", nil))
}

Now run the server as a background job and curl it:

$ go run main.go &
[1] 88440

$ curl localhost:8080/
Hello Go!

$ kill %1
[1]  + 88440 terminated  go run main.go

Containerize the HTTP Server

Verify that Docker is installed and running:

$ docker --version
Docker version 1.12.2

$ docker ps &> /dev/null; echo $?
0  

Now create a Dockerfile describing how to build our container:

FROM golang  
ADD . app/  
WORKDIR app/  
EXPOSE 8080  
CMD go run main.go  

Now build an image tagged hellogo:

$ docker build -t hellogo .
...
Successfully built 0cadb965de23  

Run the container in the background and curl it:

$ docker run -d -p 8080:8080 hellogo
9f09319d1a803570afde37efadd387162051095e6c4c4e3f2cc1ed9e6c706529

$ curl localhost:8080
Hello Go!

$ docker kill $(docker ps -l -q)
9f09319d1a80  

Setup Google Cloud Platform

Travel to cloud.google.com and click Try it Free to create an account and start a free trial.

From the projects list, select "Create a project" and name it hellogo.

You should arrive at the Google Cloud Platform Dashboard:

A billing account must be set on the project in order to deploy the application - travel to console.cloud.google.com/billing/projects to do so now. Once complete, the page should look like so:

Now go to cloud.google.com/sdk and install the gcloud cli.

Once gcloud is installed, run the following command to connect the cli to your project:

$ gcloud init

The init subcommand will take you through Google's multi-factor auth flow which will create an API key used by the cli to make authenticated API requests to your Google Cloud Platform account.

Make sure you've set the correct project by running this command:

$ gcloud info | grep project:
    project: [hellogo-147000]

Deploy to Google App Engine

Create a file in the hellogo project called app.yaml - this is the file Google App Engine uses to determine your environment.

runtime: custom  
env: flex  

The App Engine Flexible Environment treats runtime: custom as indicator to configure your environment entirely with Docker - this is known as a Custom Runtime in Google App Engine parlance.

Finally, deploy the service:

$ gcloud app deploy
...
Updating service [default]...done.  
Deployed service [default] to [https://hellogo-147000.appspot.com]  

The command will upload our app to the Container Registry, then instruct Google App Engine to create and start the first service of the project, default.

Once the command finishes, open the browser and view the service running live on appspot.com:

Redeploying is easy - let's update our main.go to have our HTTP server emit a different message:

fmt.Fprintln(w, "Hello from GAE!")  

Now deploy again:

$ gcloud app deploy

The service will be deployed and the newer version will be automatically promoted:

If we return to the Google Cloud Platform Dashboard and click Go to the App Engine dashboard, we'll notice a graph summarizing requests made to our service. Clicking Versions in the left hand nav will take us to a page displaying all versions of our service:

Next Steps

Before diving directly into a production setup, be sure to:

Cheers.