Migrating your App Engine app to Go 1.12+

Learn how to migrate your existing App Engine app from the Go 1.9 runtime to the Go 1.12+ runtimes of the App Engine standard environment.

Changes in the App Engine Go 1.12+ runtimes

You must make changes to your existing App Engine Go app and your deployment process in order to use the App Engine Go 1.12+ runtimes. The key differences in the new runtimes are outlined below:

Migrating from the App Engine Go SDK

The appengine package and the google.golang.org/appengine package are no longer supported. You will have to migrate to the Google Cloud client library to access equivalent Google Cloud services:

Changes to the app.yaml file

The behavior of some elements in the app.yaml configuration file has been modified:

Element Change type Description
api_version Deprecated
runtime Modified Change the runtime element to specify runtime: go112 or runtime: go113
application_readable Deprecated
builtins Deprecated
includes Deprecated
login Deprecated The Go 1.12+ runtimes do not support login. You must use alternative methods to authenticate users.
libraries Deprecated
threadsafe Deprecated All applications are presumed to be threadsafe, meaning an instance can handle multiple requests at the same time.
skip_files Deprecated Instead create a .gcloudignore file in the root directory where your app.yaml file is located. For more information, see the .gcloudignore reference.

For more information, see the app.yaml reference.

Creating a main package

Your service must include a package main statement in at least one source file.

Writing a main package

If your service doesn't already contain a main package, add the package main statement and write a main() function. At a minimum, the main() function should:

  • Read the PORT environment variable and call the http.ListenAndServe() function:

    port := os.Getenv("PORT")
    if port == "" {
    	port = "8080"
    	log.Printf("Defaulting to port %s", port)
    }
    
    log.Printf("Listening on port %s", port)
    if err := http.ListenAndServe(":"+port, nil); err != nil {
    	log.Fatal(err)
    }

Registering your HTTP handlers

You can register your HTTP handlers by choosing one of the following options:

  • The preferred method is to manually move all http.HandleFunc() calls from your packages to your main() function in your main package.
  • Alternatively, import your application's packages into your main package, ensuring each init() function that contains calls to http.HandleFunc() gets run on startup.

    You can find all packages which use the http.HandleFunc() call with the following bash script, and copy the output into your main package's import block:

    gp=$(go env GOPATH) && p=$(pwd) && pkg=${p#"$gp/src/"} && find . -name "*.go" | xargs grep "http.HandleFunc" --files-with-matches | grep -v vendor/ | grep -v '/main.go' | sed "s#\./\(.*\)/[^/]\+\.go#\t_ \"$pkg/\1\"#" | sort | uniq
    

Structuring your files

Go requires each package has its own directory. You can tell App Engine where your main package is by using main: in your project's app.yaml file. For example, if your app's file structure looked like this:

myapp/
├── app.yaml
├── foo.go
├── bar.go
└── web/
    └── main.go

Your app.yaml file would have:

runtime: go113  # or go112 for the Go 1.12 runtime

main: ./web # Relative filepath to the directory containing your main package.

For more information about the main flag, see the app.yaml reference.

Moving files to your GOPATH

Find your GOPATH by using the following command:

go env GOPATH

Move all relevant files and imports to your GOPATH. If using relative imports, such as import ./guestbook, update your imports to use the full path: import github.com/example/myapp/guestbook.

Was this page helpful? Let us know how we did:

Send feedback about...

App Engine standard environment for Go 1.12+ docs