2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ruby + Sinatra + Google App Engine スタンダード環境で Hello World

Last updated at Posted at 2020-02-09

概要

  • Google App Engine スタンダード環境で Ruby + Sinatra によるシンプルな Web アプリケーションを動かす

構成

  • Google App Engine スタンダード環境
  • Ruby 2.5
  • Web アプリケーションフレームワーク: Sinatra 2.0.8
  • テンプレートエンジン: Erb
  • Web アプリケーションサーバ: Puma 4.3

Google App Engine スタンダード環境の Ruby はベータ版

現時点(2020年2月9日現在)ではまだベータ版の状態。
ベータ版になったのは2019年8月。

Ruby support comes to App Engine standard environment | Google Cloud Blog

Ruby is now Beta on App Engine standard environment, in addition to being available on the App Engine flexible environment.

Google App Engine Ruby 2.5 Standard Environment documentation

ベータ版
この機能はプレリリース版の状態で、変更やサポート制限が行われる可能性があります。

ソースコード

ファイル一覧

├── Gemfile
├── Gemfile.lock
├── app.rb
├── app.yaml
├── config.ru
├── public
│   └── images
│       └── icon.png
└── views
    ├── error.erb
    └── hello.erb

Gemfile

sinatra-contrib は Sinatra Reloader などを使うために必要。

source 'https://rubygems.org'

gem 'puma'
gem 'sinatra'
gem 'sinatra-contrib'

Gemfile.lock

bundle install で生成された Gemfile.lock ファイル。

GEM
  remote: https://rubygems.org/
  specs:
    backports (3.16.0)
    multi_json (1.14.1)
    mustermann (1.1.1)
      ruby2_keywords (~> 0.0.1)
    nio4r (2.5.2)
    puma (4.3.1)
      nio4r (~> 2.0)
    rack (2.1.2)
    rack-protection (2.0.8.1)
      rack
    ruby2_keywords (0.0.2)
    sinatra (2.0.8.1)
      mustermann (~> 1.0)
      rack (~> 2.0)
      rack-protection (= 2.0.8.1)
      tilt (~> 2.0)
    sinatra-contrib (2.0.8.1)
      backports (>= 2.8.2)
      multi_json
      mustermann (~> 1.0)
      rack-protection (= 2.0.8.1)
      sinatra (= 2.0.8.1)
      tilt (~> 2.0)
    tilt (2.0.10)

PLATFORMS
  ruby

DEPENDENCIES
  puma
  sinatra
  sinatra-contrib

BUNDLED WITH
   2.1.4

app.rb

メイン処理をするファイル。

app.rb
require 'sinatra'
require 'sinatra/reloader' if development?

helpers do
  # HTML エスケープ用にエイリアスを作成
  include Rack::Utils
  alias_method :h, :escape_html
end

# 404 Not Found 時
not_found do
  @error_message = 'Page Not Found'
  erb :error
end

# エラー発生時
error do
  @error_message = h env['sinatra.error'].message
  erb :error
end

# Hello メッセージ表示ページ
get '/hello/:message?' do

  # q パラメータがあるときはエラーを発生させる
  raise params[:q] if params[:q]

  # Ruby のバージョンをセット
  @ruby_desc = RUBY_DESCRIPTION

  # メッセージをセット
  if params['message'] != nil
    @message = params['message']
  else
    @message = 'Hello, world!'
  end

  # 環境情報を取得
  env = {
    :dev  => settings.development?,
    :prod => settings.production?,
    :test => settings.test?
  }

  # HTML を表示
  erb :hello, :locals => env
end

app.yaml

Google App Engine 用の設定ファイル。
Google App Engine スタンダード環境でサポートされている Ruby のバージョンは 2.5。

app.yaml
runtime: ruby25

# アプリケーション起動エントリポイント
entrypoint: bundle exec rackup -s Puma -p $PORT

# 第2世代ランタイム, インスタンスクラス F1, メモリ制限 256MB, CPU制限 600MHz
instance_class: F1

# インスタンス数のオートスケール設定
automatic_scaling:
  min_idle_instances: automatic
  max_idle_instances: 1
  min_pending_latency: 3s
  max_pending_latency: 5s
  max_concurrent_requests: 5 # 許容する同時リクエスト数(指定できる最大値は80)
  target_cpu_utilization: 0.95 # インスタンス立ち上げトリガーなCPU負荷率(0.5から0.95の間で指定)
  max_instances: 1 # 最大インスタンス数

# 環境変数
env_variables:
  RACK_ENV: production

# 静的ファイル配信用設定
handlers:
- url: /images
  static_dir: public/images
  secure: always

config.ru

rackup コマンド用に config.ru を用意する。

config.ru
require './app'
run Sinatra::Application

views/error.erb

エラーページ用 HTML テンプレート。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Error page</title>
</head>
<body>
<p><%= @error_message %></p>
</body>
</html>

views/hello.erb

ページ用 HTML テンプレート。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, World!</title>
</head>
<body>
<p><%= h @message %></p>
<p>Ruby: <%= h @ruby_desc %></p>
<p>development?: <%= dev  %></p>
<p>production?:  <%= prod %></p>
<p>test?:        <%= test %></p>
<p><img src="/images/icon.png" alt="icon" title="icon"></p>
</body>
</html>

ローカルでサーバを起動

bundle install で環境を構築

bundle install コマンドで Gemfile.lock または Gemfile に記載してあるパッケージがインストールされる。

development 環境

開発時に使う起動方法。
RACK_ENV=development を指定する。
エラーメッセージなどがわかりやすく Web ページ上に表示される。

$ RACK_ENV=development bundle exec rackup -s Puma
Puma starting in single mode...
* Version 4.3.1 (ruby 2.5.7-p206), codename: Mysterious Traveller
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://127.0.0.1:9292
* Listening on tcp://[::1]:9292
Use Ctrl-C to stop

production 環境

動作確認時に使う起動方法。
RACK_ENV=production を指定する。

$ RACK_ENV=production bundle exec rackup -s Puma
Puma starting in single mode...
* Version 4.3.1 (ruby 2.5.7-p206), codename: Mysterious Traveller
* Min threads: 0, max threads: 16
* Environment: production
* Listening on tcp://0.0.0.0:9292
Use Ctrl-C to stop

Google App Engine にデプロイ

事前にデプロイ先のプロジェクトの作成や gcloud コマンドでアカウント認証などをしておく(課金設定等のためCUIコマンドだけでは完結しないと思われる)。

参考: Quickstart for Ruby in the App Engine Standard Environment

$ gcloud auth login
$ gcloud projects create [YOUR_PROJECT_ID] --set-as-default
$ gcloud app create --project=[YOUR_PROJECT_ID]
$ gcloud config set project [YOUR_PROJECT_ID]
$ gcloud config list

gcloud app deploy コマンドで Google App Engine にデプロイする。

$ gcloud app deploy

Google App Engine のサーバにアクセス

200 OK

$ curl -i "https://simple-sample.appspot.com/hello/こんにちは世界<>\"'&"
HTTP/2 200 
content-type: text/html;charset=utf-8
vary: Accept-Encoding
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-cloud-trace-context: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;o=1
date: Sun, 09 Feb 2020 04:20:35 GMT
server: Google Frontend
content-length: 379
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, World!</title>
</head>
<body>
<p>こんにちは世界&lt;&gt;&quot;&#x27;&amp;</p>
<p>Ruby: ruby 2.5.7p206 (2019-10-01 revision 67816) [x86_64-linux]</p>
<p>development?: false</p>
<p>production?:  true</p>
<p>test?:        false</p>
<p><img src="/images/icon.png" alt="icon" title="icon"></p>
</body>
</html>

404 Not Found

$ curl -i https://simple-sample.appspot.com/
HTTP/2 404 
content-type: text/html;charset=utf-8
vary: Accept-Encoding
x-cascade: pass
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-cloud-trace-context: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
date: Sun, 09 Feb 2020 04:14:11 GMT
server: Google Frontend
content-length: 133
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Error page</title>
</head>
<body>
<p>Page Not Found</p>
</body>
</html>

500 Internal Server Error

$ curl -i https://simple-sample.appspot.com/hello/?q=テスト用エラー
HTTP/2 500 
content-type: text/html;charset=utf-8
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-cloud-trace-context: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;o=1
date: Sun, 09 Feb 2020 04:14:37 GMT
server: Google Frontend
content-length: 140
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Error page</title>
</head>
<body>
<p>テスト用エラー</p>
</body>
</html>

画像へのアクセス

app.yaml の handlers で静的配信指定しているのでレスポンスヘッダに Cache-Control や Expires が設定される。

$ curl -i https://simple-sample.appspot.com/images/icon.png
HTTP/2 200 
date: Sun, 09 Feb 2020 04:14:50 GMT
expires: Sun, 09 Feb 2020 04:24:50 GMT
etag: "XXXXXX"
x-cloud-trace-context: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
content-type: image/png
server: Google Frontend
cache-control: public, max-age=600
content-length: 18136
age: 0
alt-svc: quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000

参考資料

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?