Building Custom Runtimes

A custom runtime allows you to easily deploy and run web applications written in any language. The App Engine flexible environment provides the scaling, monitoring, and load balancing infrastructure, so you can focus on building your application.

To create a custom runtime you need:

  • An app.yaml file that describes your application's runtime configuration.
  • A Dockerfile that configures the runtime environment. In many cases, this can be just one line specifying a base image.
  • To ensure your application is listening on port 8080 and has request handlers that respond to lifecycle events, such as start, stop, and health check requests.

Create an app.yaml file

You must use an app.yaml configuration file with the following settings:

runtime: custom
env: flex

For information about configuring other flexible environment settings for your app, see Configuring your App with app.yaml.

Create a Dockerfile

The Dockerfile is always named Dockerfile and should be placed in the same directory with the corresponding app.yaml file. This remains true if you are customizing a Java runtime and using gcloud commands, however other tooling might have different requirements. For example, Cloud SDK-based Java tools such as the Maven, Gradle, Eclipse, and IntelliJ plugins require that the Dockerfile is in the src/main/docker/Dockerfile directory and that the app.yaml file is in the src/main/appengine/app.yamldirectory.

Comprehensive documentation is available on the Docker website. You need to do this whether you use your own base image or one of Google's base images. For simplicity, this page shows an example using a Google-provided base image.

Configuring the Dockerfile

The first command in a Dockerfile is usually a FROM command specifying a base image.

The FROM command for each of the Google-provided base images is shown in the following table, along with the github project used to build the image:

Runtime Command Note
Go
github project
FROM gcr.io/google-appengine/golang APIs require Go libraries.
Java (Open JDK 8 only)
github project
FROM gcr.io/google-appengine/openjdk Dockerfiles for Java.
Java (Open JDK 8 + Eclipse Jetty 9.3)
github project
FROM gcr.io/google-appengine/jetty Dockerfiles for Java.
Python 2.7 & 3.6
github project
FROM gcr.io/google-appengine/python
Node.js
github project
FROM gcr.io/google-appengine/nodejs
Ruby
github project
FROM gcr.io/google-appengine/ruby
PHP
github project
FROM gcr.io/google-appengine/php

Using App Engine service APIs

To access the App Engine service APIs from a Go app that is running the golang base 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.

Example 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

where 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.

Developing code for custom runtimes

This section describes behavior that your code must implement whether you use a Google-provided base image or your own base image.

Listen 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.

Lifecycle events

Application Shutdown

When shutting down an instance, App Engine flexible environment normally sends a 'STOP' (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 a 'KILL' (SIGKILL) signal.

In rare cases, outages can prevents App Engine from providing 30 seconds of shutdown time, which means the 'STOP' and '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 flexible environment is periodically sent health check requests.

If you create a custom runtime your app must handle health check requests or disable them, otherwise, the app won't come up properly.

A health check is an HTTP request to the URL /_ah/health. A healthy application should respond with status code 200.

At its simplest, an application can check that its serving stack is up and running; it might also perform more sophisticated checks, such as ensuring any background processes are running.

To disable health checking, add this line to your app's configuration file:

enable_health_check: False

Using Google Cloud Platform services

Applications running in the flexible environment can access the Google Cloud Client Libraries or any third-party services via standard APIs.

API clients

With custom runtimes, client libraries can use the Application Default Credentials to authenticate with and call Google APIs.

Alternatively, you can authenticate your application directly with access tokens using the Compute Engine Metadata API. You can then use these access tokens in API requests, such as requests against Google Cloud Storage and Google Cloud Datastore services and resources.

Logging

When a request is sent to your application running in App Engine, request and response details are logged automatically, and 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 stdout and stderr. These files are automatically collected and can be viewed in the Logs Viewer. Only the most recent entries to stdout and 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
crash.log text Information logged when setup fails. If your application fails to run, check this log.
monitoring.* text Information from the Docker container publishing data to Cloud Monitoring.
shutdown.log text Information logged on shutdown.
stdout text Standard output from your app.
stderr text Standard error from your container.
syslog text The VM syslog, outside of the Docker container.

Monitor your resources on the go

Get the Google Cloud Console app to help you manage your projects.

Send feedback about...

Custom runtimes for the App Engine flexible environment