Entorno de ejecución de Ruby

El tiempo de ejecución de Ruby es la pila de software responsable de instalar el código de tu aplicación y sus dependencias, y, a continuación, ejecutar esa aplicación en el entorno flexible.

Versiones de Ruby

Ruby 3.4 usa paquetes de compilación. Para ver la lista completa de versiones de Ruby admitidas y sus correspondientes versiones de Ubuntu, consulta la programación de asistencia de tiempo de ejecución.

Para usar una versión compatible de Ruby, debes hacer lo siguiente:

  • Especifica una versión de Ruby en tu Gemfile.

    RUBY VERSION
      ruby 3.4.x
    
  • Instala la versión 420.0.0 o posterior de gcloud CLI. Puedes actualizar tus herramientas de CLI ejecutando el comando gcloud components update. Para ver la versión instalada, puedes ejecutar el comando gcloud version.

  • Especifica el ajuste operating_system en el archivo app.yaml:

      runtime: ruby
      env: flex
    
      runtime_config:
          operating_system: "ubuntu22"
    
  • También puedes especificar una versión del intérprete de Ruby con un archivo .ruby-version en el directorio de tu aplicación. Por ejemplo, 3.4.x

Versiones anteriores

Para usar la versión 3.1 o anterior del entorno de ejecución de Ruby, especifica una versión del intérprete de Ruby mediante un archivo .ruby-version en el directorio de tu aplicación.

Cuando este archivo está presente, el tiempo de ejecución instala la versión solicitada de Ruby al implementar la aplicación con rbenv. Si no se puede instalar la versión solicitada, App Engine muestra un mensaje de error durante la implementación.

Si no proporcionas un archivo .ruby-version, el tiempo de ejecución de Ruby usará la versión 2.7 de forma predeterminada. Ten en cuenta que el valor predeterminado puede cambiar en cualquier momento, por lo que te recomendamos que tu aplicación especifique una versión de Ruby.

Compatibilidad con otros entornos de ejecución de Ruby

Si necesitas usar una versión de Ruby que no sea compatible, puedes crear un runtime personalizado y seleccionar una imagen base válida con la versión de Ruby que necesites.

Para obtener imágenes base proporcionadas por Google o imágenes base de Docker Ruby, consulta Crear tiempos de ejecución personalizados.

Dependencias

El tiempo de ejecución busca un archivo Gemfile en el directorio de origen de tu aplicación y usa Bundler para instalar las dependencias antes de iniciar la aplicación. Para obtener más información sobre cómo declarar y gestionar paquetes, consulta Usar bibliotecas de Ruby.

Usar bibliotecas de C con Ruby

En el caso de las bibliotecas de Ruby que requieren extensiones de C, los encabezados de la versión actual de Ruby y los siguientes paquetes de Ubuntu están preinstalados en el sistema.

  • 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

Estos paquetes permiten instalar las bibliotecas de Ruby más populares. Si tu aplicación requiere dependencias adicionales a nivel de sistema operativo, tendrás que usar un runtime personalizado basado en este runtime para instalar los paquetes correspondientes.

Inicio de la aplicación

El tiempo de ejecución inicia tu aplicación con el entrypoint definido en app.yaml. El punto de entrada debe iniciar un proceso que responda a las solicitudes HTTP en el puerto definido por la variable de entorno PORT. Por ejemplo:

entrypoint: bundle exec rails server -p $PORT

La mayoría de las aplicaciones web usan un servidor web compatible con Rack, como Puma, Unicorn o Thin.

Debes añadir el servidor como dependencia en el archivo de configuración Gemfile de tu aplicación. El tiempo de ejecución instalará todas las dependencias antes de que se llame a tu punto de entrada.

source "https://rubygems.org"

gem "rack"
gem "puma"

Un ejemplo de punto de entrada que usa Puma para una aplicación Rails:

entrypoint: bundle exec rails server Puma -p $PORT

Un ejemplo de punto de entrada que usa Puma para cualquier aplicación Rack:

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

En el caso de las aplicaciones que pueden gestionar solicitudes sin un servidor Rack, solo tienes que ejecutar una secuencia de comandos de Ruby:

entrypoint: bundle exec ruby app.rb

Variables de entorno

El entorno de ejecución define las siguientes variables de entorno:

Variable de entorno Descripción
GAE_INSTANCE Nombre de la instancia actual.
GAE_MEMORY_MB Cantidad de memoria disponible para el proceso de la aplicación.
GAE_SERVICE El nombre del servicio especificado en el archivo app.yaml de tu aplicación o, si no se ha especificado ningún nombre de servicio, se define como default.
GAE_VERSION Etiqueta de versión de la aplicación actual.
GOOGLE_CLOUD_PROJECT El ID del proyecto asociado a tu aplicación, que se puede ver en la Google Cloud consola
PORT Puerto que recibirá las solicitudes HTTP.
RACK_ENV Su valor debe ser production.
RAILS_ENV Su valor debe ser production.
RAILS_SERVE_STATIC_FILES Su valor debe ser true.

Puedes definir variables de entorno adicionales con app.yaml.

Servidor de metadatos

Cada instancia de tu aplicación puede usar el servidor de metadatos de Compute Engine para consultar información sobre la instancia, como su nombre de host, su dirección IP externa, su ID de instancia, sus metadatos personalizados y la información de su cuenta de servicio. App Engine no te permite definir metadatos personalizados para cada instancia, pero puedes definir metadatos personalizados para todo el proyecto y leerlos desde tus instancias de App Engine y Compute Engine.

Esta función de ejemplo usa el servidor de metadatos para obtener una dirección IP externa de una instancia.

require "sinatra"
require "net/http"

get "/" do
  uri = URI.parse(
    "http://metadata.google.internal/computeMetadata/v1" +
    "/instance/network-interfaces/0/access-configs/0/external-ip"
  )

  request = Net::HTTP::Get.new uri.path
  request.add_field "Metadata-Flavor", "Google"

  http = Net::HTTP.new uri.host, uri.port

  response = http.request request

  "External IP: #{response.body}"
end