A custom runtime allows you to use an alternate implementation of any supported App Engine flexible language, or to customize a Google-provided one. It also allows you to write code in any other language that can handle incoming HTTP requests (example). With a custom runtime, the App Engine flexible environment provides and manages your scaling, monitoring, and load balancing infrastructure for you, so you can focus on building your application.
To create a custom runtime you must:
- Provide an
app.yamlfile that describes your application's runtime configuration to App Engine.
- Add a
Dockerfilethat internally configures the runtime environment.
- Ensure that your code follows some basic rules.
Provide an app.yaml file
app.yaml configuration file must contain at least the following settings:
runtime: custom env: flex
For information about what else you can set for your app, see Configuring your App with app.yaml.
Create a Dockerfile
Comprehensive documentation on creating Dockerfiles is available on the Docker website. If you are using a custom runtime, you must provide a Dockerfile whether you are providing your own base image or using one of Google's base images.
Specifying a Google base image
The first command in a Dockerfile is usually a
FROM command specifying a base
image. The following table shows you the
FROM command to use to specify any
Google-provided base images, along with the github project used to build the
|Java (Open JDK 8 only)
||Dockerfiles for Java.|
|Java (Open JDK 8 + Eclipse Jetty 9.3)
||Dockerfiles for Java.|
|Python 2.7 & 3.6
Using App Engine service APIsTo access the App Engine service APIs from a Go app that is running the
golangbase image, you must import the App Engine Go libraries into your source code.
Using custom Java runtimes
To customize a Java runtime and add additional directives, you must create a Dockerfile.
Dockerfile for Java 8 / Jetty 9:
FROM gcr.io/google-appengine/jetty ADD test-webapp-1.0-SNAPSHOT.war $JETTY_BASE/webapps/root.war WORKDIR $JETTY_BASE RUN java -jar $JETTY_HOME/start.jar --approve-all-licenses --add-to-startd=jmx,stats,hawtio \ && chown -R jetty:jetty $JETTY_BASE
test-webapp-1.0-SNAPSHOT.war is the name of the built WAR file in your
target/ (maven) or
build/staged-app/ (gradle) directory.
In contrast, don't need a Dockerfile to deploy your app to App Engine, if you choose to use an uncustomized base image of one of the Google-provided Java runtimes. For more information, see Java 8 runtime or Java 8 / Jetty 9 runtime.
For a complete list of all the Google-provided images, see the google-appengine project.
Naming and locating the Dockerfile
In general, the Dockerfile is always named
Dockerfile and is placed in the
same directory as the corresponding
app.yaml file. In some cases, however, the
tooling environment might have different requirements. For example, Cloud
SDK-based Java tools such as the Maven, Gradle, Eclipse, and IntelliJ plugins
Dockerfile to be in
src/main/docker/Dockerfile and the
app.yaml file to be in
src/main/appengine/app.yaml. See the
for your tooling environment for more information.
Required code structure
This section describes behavior that your code must implement whether you use a Google-provided base image or your own base image.
Listening to port 8080
The App Engine front end will route incoming requests to the appropriate module on port 8080. You must be sure that your application code is listening on 8080.
Handling lifecycle events
The App Engine flexible environment periodically sends your application certain lifecycle events.
When shutting down an instance, App Engine flexible environment normally
SIGTERM) signal to the app container. Your application does not
need to respond to this event, but your application can use it to perform any
necessary clean-up actions before the container is shut down. Under normal
conditions, the system waits up to 30 seconds for the app to stop and then sends
In rare cases, outages can prevents App Engine from providing 30 seconds
of shutdown time, which means the
KILL signals might not be sent
before an instance terminates. To handle this possibility, you should
periodically checkpoint the state of your instance, using it primarily as an
in-memory cache rather than a reliable data store.
Health check requests
By default, an application running in the App Engine flexible environment is periodically sent some form of health check request.
If you create a custom runtime your app must either handle the type of health
check requests configured in your
app.yaml file or disable these checks all
together. Otherwise, your app won't come up properly.
Whichever type of health check you decide to use, a healthy application should
respond with an HTTP status code
If you do not wish to use this health check, add this line to your app's
Integrating your application with Google Cloud Platform
Applications running in custom runtimes can use the Google Cloud Client Libraries to access Google Cloud Platform services. Applications in custom runtimes can also use any third-party service via standard APIs.
Authenticating with Google Cloud Platform services
In general, Application Default Credentials provide the simplest way to authenticate with and call Google APIs.
It is possible to authenticate your application directly with access tokens using the Compute Engine Metadata API, but this is considerably more complex. You can then use these access tokens in API requests, such as requests against Cloud Storage and Cloud Datastore services and resources.
For more information on authentication options, see here.
When a request is sent to your application running in App Engine, the request and response details are logged automatically. They can be viewed in the Google Cloud Platform Console Stackdriver Logs Viewer.
When your application handles a request, it can also
write its own logging messages to
stderr. These files are
automatically collected and can be viewed in the Logs Viewer. Only the most
recent entries to
stderr are retained, in order
to limit their size.
The request and application logs for your app are collected by a Stackdriver Logging agent and are kept for a maximum of 90 days, up to a maximum size of 1GB. If you want to store your logs for a longer period or store a larger size than 1GB, you can export your logs to Cloud Storage. You can also export your logs to BigQuery and Pub/Sub for further processing.
Other logs are also available for your use. The following are some of the logs that are configured by default:
|Log name||Payload type||Purpose|
||text||Information logged when setup fails. If your application fails to run, check this log.|
||text||Information from the Docker container publishing data to Cloud Monitoring.|
||text||Information logged on shutdown.|
||text||Standard output from your app.|
||text||Standard error from your container.|
||text||The VM syslog, outside of the Docker container.|