O ambiente de execução do Ruby

O ambiente de execução do Java é a pilha de software responsável por instalar o código e as dependências do aplicativo e executá-lo no ambiente flexível.

Versões do Ruby

O Ruby 3.3 usa buildpacks. Para ver a lista completa de versões compatíveis do Ruby e a versão correspondente do Ubuntu, consulte a Programação de suporte ao ambiente de execução.

Para usar uma versão compatível do Ruby, você precisa:

  • Especifique uma versão do Ruby no Gemfile.

    RUBY VERSION
      ruby 3.3.x
    
  • Instalar a versão da CLI gcloud 420.0.0 ou posterior do Google Analytics. É possível atualizar as ferramentas da CLI executando o comando gcloud components update. Para conferir a versão instalada, execute o comando gcloud version.

  • Especifique a configuração operating_system no arquivo app.yaml:

      runtime: ruby
      env: flex
    
      runtime_config:
          operating_system: "ubuntu22"
    
  • Também é possível especificar uma versão do interpretador do Ruby usando um arquivo .ruby-version no diretório do aplicativo. Por exemplo, 3.3.x

Versões anteriores

Para o ambiente de execução do Ruby versão 3.1 e anteriores, especifique uma versão do interpretador do Ruby usando um arquivo .ruby-version no diretório do aplicativo.

Quando esse arquivo está presente, o ambiente de execução instala a versão solicitada do Ruby durante a implantação do aplicativo usando o rbenv. Se não for possível instalar a versão solicitada, o App Engine mostrará uma mensagem de erro durante a implantação.

Se você não fornecer um arquivo .ruby-version, o ambiente de execução do Ruby será a versão padrão 2.7. Como o padrão pode ser alterado a qualquer momento, é recomendável que seu aplicativo especifique uma versão do Ruby.

Suporte a outros ambientes de execução do Ruby

Se você precisa usar uma versão do Ruby que não é compatível, crie um ambiente de execução personalizado e selecione um imagem de base válida com a versão do Ruby necessária.

Para imagens de base fornecidas pelo Google ou Imagens de base do Docker Ruby, consulte Como criar ambientes de execução personalizados.

Dependências

O ambiente de execução procura um arquivo Gemfile no diretório de origem do aplicativo e usa o Bundler para instalar as dependências antes de iniciar o aplicativo. Para mais informações sobre como declarar e gerenciar pacotes, consulte Como usar bibliotecas em Ruby.

Como usar bibliotecas C com o Ruby

No caso das bibliotecas do Ruby que requerem extensões C, os cabeçalhos para a versão atual do Ruby e os pacotes Ubuntu a seguir já estão pré-instalados no 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

Com esses pacotes, é possível instalar as bibliotecas mais usadas do Ruby. Se o aplicativo requer mais dependências no nível do sistema operacional, use um ambiente de execução personalizado baseado no ambiente de execução necessário para instalar os pacotes apropriados.

Inicialização do aplicativo

O ambiente de execução inicia seu aplicativo usando o entrypoint definido em app.yaml. O entrypoint deve iniciar um processo que responde a solicitações HTTP na porta definida pela variável de ambiente PORT. Por exemplo:

entrypoint: bundle exec rails server -p $PORT

A maioria dos aplicativos da Web usa um servidor compatível com Rack, como Puma, Unicorn ou Thin.

É preciso adicionar o servidor como uma dependência no arquivo de configuração Gemfile de seu aplicativo. O ambiente de execução instalará todas as dependências antes que o ponto de entrada seja chamado.

source "https://rubygems.org"

gem "rack"
gem "puma"

Um exemplo de entrypoint que usa puma para um aplicativo do Rails:

entrypoint: bundle exec rails server Puma -p $PORT

Um exemplo de entrypoint que usa puma para um aplicativo do Rack:

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

No caso de aplicativos capazes de processar solicitações sem um servidor Rack, basta executar um script ruby:

entrypoint: bundle exec ruby app.rb

Variáveis de ambiente

As variáveis de ambiente a seguir são definidas pelo ambiente de execução:

Variável de ambiente Descrição
GAE_INSTANCE O nome da instância atual.
GAE_MEMORY_MB A quantidade de memória disponível para o processo do aplicativo.
GAE_SERVICE O nome do serviço especificado no arquivo app.yaml do aplicativo. Se nenhum nome de serviço for especificado, será definido como default.
GAE_VERSION O rótulo da versão do aplicativo atual.
GOOGLE_CLOUD_PROJECT O ID do projeto associado ao seu aplicativo, que fica visível no console do Google Cloud
PORT A porta que receberá as solicitações HTTP.
RACK_ENV Defina como production.
RAILS_ENV Defina como production.
RAILS_SERVE_STATIC_FILES Defina como true.

Para definir variáveis extras de ambiente, use app.yaml.

Servidor de metadados

Cada instância do aplicativo pode usar o servidor de metadados do Compute Engine para consultar informações sobre a instância, incluindo o nome do host, o endereço IP externo, o código da instância, metadados personalizados e informações sobre a conta de serviço. Não é possível definir metadados personalizados para cada instância no App Engine. Em vez disso, defina metadados personalizados para o projeto e leia esses metadados a partir das instâncias do App Engine e do Compute Engine.

Este exemplo de função usa o servidor de metadados para conseguir um endereço IP externo de uma instância.

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