Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: Ruby30周年記念イベント、37signalsのデプロイツールmrskほか(20230308後編)

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Ruby

🔗 Ruby30周年記念イベント関連情報


つっつきボイス:「当日途中までしか見られなかったので動画ありがたい」「動画にいつの間にか見出しも付けてくれていて助かります↓」


https://www.youtube.com/watch?v=cmd5NdMjHkI&より

「関連記事も出ています↓」

参考: Ruby 30周年記念イベントにLT登壇した - koicの日記
参考: Ruby30周年イベント(前編):Rubyを作る前のまつもと氏が作りかけた、Rubyの原点となるプログラミング言語「Tish」 - Publickey
参考: Ruby30周年イベント(中編)~言語を「作りたい」と思ってから10年以上経って、スキルと環境が追いついてRubyを作ることができるようになった - Publickey
参考: Ruby30周年イベント(後編):まつもと氏「Static Compiler for Ruby」を作りたい。道具立ては揃ってきた - Publickey -- つっつき後に公開されました

🔗 通貨を扱うgem

RubyMoney/money - GitHub

RubyMoney/money-rails - GitHub


つっつきボイス:「通貨を扱うgemがいくつかあったのでリストアップしました: money-railsはmoneyに依存したRails向けgemです」「moneyとmoney-railsは定番のgemですね」「money gemにdeprecationも出ていました↓」

現在のデフォルトの振る舞いでは、I18nロケールを常に最初にチェックしてから「通貨ごと」のローカリゼーションにフォールバックしている。これは非推奨化され、次のメジャーリリースでは削除されて明示的に振る舞いを定義する形になる。
https://github.com/RubyMoney/money#deprecationより

「money gemのCHANGELOGによると、文字列を通貨に変換する機能は以下のmonetize gemに切り出されたそうです↓」

RubyMoney/monetize - GitHub

🔗 Shopifyのruby-lspで開発エクスペリエンスを向上させる


つっつきボイス:「以前取り上げたruby-lsp(ウォッチ20220607)をShopifyが記事にしていました」「language serverはいいですよね」「個人的にはJetBrains IDEのlanguage serverを使いたい気持ち: ライセンス必要でもいいから」

Shopify/ruby-lsp - GitHub

🔗 Standard RubyをVSCode拡張で使う(Ruby Weeklyより)


つっつきボイス:「以前も取り上げたtestdoubleのstandard(Standard Ruby、standardrbとも)というRuby向けの高速linter(ウォッチ20210316)をVSCode拡張経由で使えるという記事です」「Standard Rubyと同様にVSCode拡張もtestdouble.comが作っていて安心感ありそう: VSCodeユーザーは使ってみてもいいかも」

testdouble/standard - GitHub

参考: Standard Ruby - Visual Studio Marketplace

参考: Test Double | An Agency Improving the World's Software

🔗 CGIに追加された新しいエスケープメソッド


つっつきボイス:「CGI::EscapeescapeURIComponentなどが追加されたんですね」

# 同記事より
require 'cgi'

url = "https://example.com/some/#{ CGI.escapeURIComponent path_component }" + 
  "?#{CGI.escapeURIComponent my_key}=#{CGI.escapeURIComponent my_value}"

「ところで記事ではRuby 3.2から入ったと書かれているけど、APIドキュメントはRuby 3.1からありますね↓」「あら」

参考: module CGI::Escape - Documentation for Ruby 3.2
参考: module CGI::Escape - RDoc Documentation for Ruby 3.1

つっつき後に調べてみると、Ruby 3.1のdefault cgi gemでもCGI.escapeURIComponentは動きました。Ruby 3.0のdefault cgi gemでは動きませんでした。

$ ruby -v
ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [arm64-darwin22]
$ irb
irb(main):001:0> require 'cgi'
=> true
irb(main):002:0> url = "https://example.com/some/#{ CGI.escapeURIComponent 'sdf<>& 123' }"
=> "https://example.com/some/sdf%3C%3E%26%20123"

  • ドキュメントでRFC3986を引用しているのが親切(URLやHTMLのエスケープにはさまざまな規格や誤りが乱立していて実装が混乱しているこの荒れた世界では珍しい)。
  • /%2Fにエスケープするので、よくも悪くも/を含む文字列をパスコンポーネントに埋め込むのに使える。
  • スペース%20にエスケープする。これはクエリ文字列でもパスコンポーネントでも合法で正しい。
  • 動作が逆のCGI.unescapeURIComponentも利用可能。
    同記事より

「以前は別の方法でエスケープしてたのが非推奨になってたような覚えがある」「URI.escapeは非推奨の後にRuby 3.0で削除されてたのね」

# 同記事より
# やってはいけない: URI.escapeは使わないこと
url = "https://example.com?key=#{ URI.escape value }"
 
# これもやってはいけない: URI.escapeは使わないこと
url = "https://example.com?" + 
   query_hash.collect { |k, v| "#{URI.escape k}=#{URI.escape v}"}.join("&")

参考: URI.encode (Ruby 2.7.0 リファレンスマニュアル)

このメソッドは obsolete です。
代わりに ERB::Util.#url_encode, CGI.escape, URI.encode_www_form_component, WEBrick::HTTPUtils.#escape_form, WEBrick::HTTPUtils.#escape などの使用を検討してください。詳細は ruby-core:29293 からのスレッドを参照してください。
URI.encode (Ruby 2.7.0 リファレンスマニュアル)より


なお、RuboCopにもURI.encodeを検出するcopがあります。CGI.escapeURIComponentCGI.unescapeURIComponentへの置き換えについての言及はまだないようです。

参考: Class: RuboCop::Cop::Lint::UriEscapeUnescape — Documentation for rubocop (1.48.0)

🔗 設計・セキュリティ

🔗 badtodo: セキュリティ実習・検証用の脆弱性入りWebアプリ

ockeghem/badtodo - GitHub


つっつきボイス:「徳丸先生が心血を注いで作ったbadtodoが話題になってますね」「通称"やられサイト"ですか」「"対応している脆弱性"という書き方が新鮮」「PHPのバージョンは5.3.3か」「脆弱性に対して適切な対策を取るには、実際にどんな攻撃が可能かも含めて理解する必要がありますね: そのために有用なツール👍」

参考: 情報セキュリティ企業が“脆弱性だらけのWebアプリ”無償公開 実習用の題材に - ITmedia NEWS

🔗クラウド/コンテナ/インフラ/Serverless

🔗 mrsk: 37signalsの多機能なコンテナデプロイツール

mrsked/mrsk - GitHub


つっつきボイス:「mrskも話題になっている」「クラウドとベアメタルを問わずにアプリのDockerコンテナをデプロイできるという触れ込みですね」「37signalsのHEYもこのmrskを使ってデプロイ先をクラウドから自社内サーバーに乗り換えたそうです」

「引っ越した理由って何でしょう?」「クラウド課金が高いからだそうです」「DHHのブログ↓を眺めてみると、クラウドの利点は主に"フルマネージドサービスはアプリの立ち上げ期に便利"、"大きな負荷変動に対応しやすい"という2点だけど、現在の37signalsはどちらにも該当しないのでクラウドの課金が割りに合わないと考えたようですね」「なるほど」

参考: Why we're leaving the cloud

「そういえばpixivは長らく自社サーバーで運用していましたけど、後にデータセンターに引っ越してましたね」「pixivのサーバーラックの写真をネットで見たことあったかも」

参考: ASCII.jp:さらば自社サーバールーム!pixiv、白河データセンターに移る (1/2)

laisoさんのこの記事↓も含めて、DHHの言いたいことはおおむね理解できますね: 自社サーバーに置くかどうかは、コスト以外にも主に自前でメンテできるかが重要で、サービス内容や規模、ディザスタリカバリやメンバーの出入りなどいろんな要素があるので一概には言えませんが」

参考: 最近のDHH「サーバーレスをやめろ」 - laiso
参考: ディザスタリカバリ - Wikipedia

「mrskのREADMEを見ると"コンテナのためのCapistrano"みたいなものという感じのことが書かれていました↓」「実際そうだと思います: ベアメタルサーバーにデプロイするようなツールはCapistrano以降あまり目立ったものがなくて、アプリをDockerコンテナで自社サーバーやAWS EC2などにデプロイしようとすると、自前でスクリプトをたくさん書いて実行することが多かったので、mrskはそういうユーザー層にはアピールしそう👍」「なるほど」「結局色んな人が同じようなものを作っているんですよね」

Capistrano/Kubernetes/Docker Swarmでいいのでは?
MRSKは基本的に「コンテナ用Capistrano」です。事前にサーバーを注意深くセットアップする必要もありませんし、サーバーで適切なバージョンのRubyやその他の依存関係を事前に準備しておく必要もありません。必要なものはすべてDockerイメージの中で動きます。真新しいUbuntuサーバー(でも何でも)を起動してMRSKのリストサーバーに追加すれば、Dockerで自動プロビジョニングされて即座に実行されます。Dockerレイヤキャッシュ機能によってデプロイも高速化され、サーバーに煩わされることも減ります。さらに、MRSKでビルドしたイメージは、後でCIや内部調査にも転用できます。

Kubernetesは猛獣です。独自ハードウェア上での運用は気の小さい人には向いていません。他の誰かのプラットフォーム上で動かすのであれば(Renderがやっているような透過的運用か、AWSやGCP上で明示的に運用するか)、Kubernetesは良いオプションですが、クラウドと独自ハードウェアの間を自由に移動したり両者を混在させたりするなら、MRSKの方がずっとシンプルです。MRSKでは基本的なDockerコマンドが呼び出されているだけです。

Docker SwarmはKubernetesよりずっとシンプルですが、それでもステートのreconciliation(調整)を利用する宣言的モデル上に構築される点は同じです。MRSKはあえてCapistranoと同様の命令的コマンド中心の設計を採用しています。

最終的にWebアプリのデプロイ方法はいくらでも存在しますが、MRSKは、私たち37signalsが、現代のコンテナ化ツールのメリットを失わずにHEYをクラウドから自社に取り戻すのに使っているツールキットなのです。
mrsk READMEより抜粋

capistrano/capistrano - GitHub

「READMEに書かれているように、Kubernetesのようなクラスタを健全な形で自社運用するのは負荷がとても大きくて、スキルの高い専任インフラチームが要求されるんですよ」「たしかにKubernetesみたいなものはクラウドサービスに乗っかる方が楽ですよね」「Kubernetesは元々Googleが自社用に作ったものなので、小さな組織が自前で運用するのはオーバーキルでしょうね」

参考: Kubernetes - Wikipedia

🔗 GitHub Packages


つっつきボイス:「mrskのREADMEで、このGitHub Packagesがデプロイ先のひとつにリストアップされていて今頃知りました」「GitHub Packagesはもう使ってます〜」「GitHubにDockerコンテナをデプロイできるのね、なるほど」

価格を見てみると無料版はストレージが500MBまでか」「GitHub Actions経由のデータ転送は無制限で、それ以外経由のデータ転送は月1GBまでなのね」「追加のデータ転送は1GBあたり0.50ドル: 派手に使うと費用がかさみそう」

「以下の記事では自社用のgemサーバーをGitHub Packagesで構築したそうです」「gemサーバーならサイズも小さいし、運用の手間が少ない方が嬉しいですよね」

参考: GitHub Packages を使ってプライベート gem を社内限定で公開した - Feedforce Developer Blog

🔗JavaScript

🔗 Turbo v7.3.0リリースと、DeviseのHotwire/Turbo対応


つっつきボイス:「お、Turboの新バージョンがリリースされたんですね」「Turbo関連のドキュメントがなかなか更新されていなかったんですが、今回は更新されました↓」「それだけ機能が増えてきたんでしょうね」

参考: Merge pull request #129 from hotwired/missing-frame-docs · hotwired/turbo-site@dcb8292
参考: Turbo Handbook


「Turboといえば、DeviseがHotwire/Turboに対応したそうです↓」「お〜ついに」「これでDeviseに関連するフロントエンド系gemもアップデートされるようになるかも」「Turbo Streamにも対応ですって」

参考: devise/CHANGELOG.md at v4.9.0 · heartcombo/deviseRuby Weeklyより)

「アップグレードガイドも出ている↓」

参考: How To: Upgrade to Devise 4.9.0 [Hotwire Turbo integration] · heartcombo/devise Wiki

🔗言語/ツール/OS/CPU

🔗 Homebrew 4.0がリリース(Publickeyより)


つっつきボイス:「Homebrew 4.0がリリースされたのでアップグレードしてみると、たしかにbrew upgradeが速くなりました」「マジですか、インストールしようっと」

参考: macOS(またはLinux)用パッケージマネージャー — Homebrew
リリースノート: 4.0.0 — Homebrew


後編は以上です。

バックナンバー(2023年度第1四半期)

週刊Railsウォッチ: Action Mailerプレビューで全メールヘッダーを表示可能に、rubocop-graphqlほか(20230307前編)

Ruby Weekly

Publickey

publickey_banner_captured


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。