The Ruby runtime

The Ruby runtime is the software stack responsible for installing your application code and dependencies, and then running that application in the flexible environment.

  • Version 3.2 is built using buildpacks, which requires you to choose an operating system in your app.yaml file. For example, to use Ruby 3.2, you must specify Ubuntu 22 as the operating system.

  • Version 3.1 and earlier are built using Docker.

For the full list of supported Ruby versions, and their corresponding Ubuntu version, see the Runtime support schedule.


New runtime versions

For version 3.2, you must include the runtime_config and operating_system settings in your app.yaml file to specify an operating system.

To use Ruby 3.2, you must:

  • Specify a Ruby version in your Gemfile.

      ruby 3.2.x
  • Install gcloud CLI version 420.0.0 or later. You can update your CLI tooling by running the gcloud components update command. To view your installed version, you can run the gcloud version command.

  • Specify the operating_system setting in your app.yaml file:

      runtime: ruby
      env: flex
          operating_system: "ubuntu22"

Optionally, you can specify a version of the Ruby interpreter using a .ruby-version file in your application directory. For example,


Previous versions

For Ruby runtime version 3.1 and earlier, specify a version of the Ruby interpreter using a .ruby-version file in your application directory.

When this file is present, the runtime installs the requested version of Ruby when you deploy your application, using rbenv. If the requested version cannot be installed, App Engine shows an error message during deployment.

If you do not provide a .ruby-version file, the Ruby runtime defaults to version 2.7. Note that the default can change at any time, so it is recommended that your app specifies a Ruby version.


The runtime looks for a Gemfile file in your application's source directory and uses Bundler to install any dependencies before starting your application. For more information on declaring and managing packages, see Using Ruby Libraries.

Using C libraries with Ruby

For Ruby libraries that require C extensions, the headers for the current Ruby version and the following Ubuntu packages are pre-installed on the system.

  • autoconf
  • build-essential
  • ca-certificates
  • cmake
  • curl
  • file
  • git
  • imagemagick
  • libcurl3
  • libcurl3-gnutls
  • libcurl4-openssl-dev
  • libffi-dev
  • libgdbm-dev
  • libgit2-dev
  • libgmp-dev
  • libicu-dev
  • libjemalloc-dev
  • libjemalloc1
  • libmagickwand-dev
  • libmysqlclient-dev
  • libncurses5-dev
  • libpq-dev
  • libqdbm-dev
  • libreadline6-dev
  • libsqlite3-dev
  • libssl-dev
  • libxml2-dev
  • libxslt-dev
  • libyaml-dev
  • libz-dev
  • systemtap
  • tzdata

These packages allow the installation of most popular Ruby libraries. If your application requires additional operating-system level dependencies, you will need to use a custom runtime based on this runtime to install the appropriate packages.

Application startup

The runtime starts your application using the entrypoint defined in app.yaml. The entrypoint should start a process that responds to HTTP requests on the port defined by the environment variable PORT. For example:

entrypoint: bundle exec rails server -p $PORT

Most web applications use a Rack-supported web server such as Puma, Unicorn or Thin.

You must add the server as a dependency in your application's Gemfile configuration file. The runtime will install all dependencies before your entrypoint is called.

source ""

gem "rack"
gem "puma"

An example entrypoint using puma for a Rails application:

entrypoint: bundle exec rails server Puma -p $PORT

An example entrypoint using puma for any Rack application:

entrypoint: bundle exec rackup -s Puma -p $PORT

For applications that can handle requests without a Rack server, you can just execute a ruby script:

entrypoint: bundle exec ruby app.rb

Extending the runtime

You can use custom runtimes to add additional functionality to a Ruby app running in the App Engine flexible environment. To configure a custom runtime, replace the following line in your app.yaml file:

runtime: ruby

with this line:

runtime: custom

You must also add Dockerfile and .dockerignore files in the same directory that contains the app.yaml file.

Visit the Custom runtimes documentation to learn how to define a Dockerfile in a custom runtime.

Environment variables

The following environment variables are set by the runtime environment:

Environment Variable Description
GAE_INSTANCE The name of the current instance.
GAE_MEMORY_MB The amount of memory available to the application process.
GAE_SERVICE The service name specified in your application's app.yaml file, or if no service name is specified, it is set to default.
GAE_VERSION The version label of the current application.
GOOGLE_CLOUD_PROJECT The Project ID associated with your application, which is visible in the Google Cloud console
PORT The port that will receive HTTP requests.
RACK_ENV Set to production.
RAILS_ENV Set to production.

You can set additional environment variables with app.yaml.

Metadata server

Each instance of your application can use the Compute Engine metadata server to query information about the instance, including its host name, external IP address, instance ID, custom metadata, and service account information. App Engine does not allow you to set custom metadata for each instance, but you can set project-wide custom metadata and read it from your App Engine and Compute Engine instances.

This example function uses the metadata server to get an external IP address for instances running Ruby runtime version 3.1 and earlier, and for instances running 3.2 and later. Note that you must update your app.yaml file to use the new version. See Ruby runtime for more information about using the new runtimes.

require "sinatra"
require "net/http"

get "/" do
  uri = URI.parse(
    "" +

  request = uri.path
  request.add_field "Metadata-Flavor", "Google"

  http =, uri.port

  response = http.request request

  "External IP: #{response.body}"