Rails アプリケーションを Github Codespaces で動かすには
この記事では、 Rails アプリケーションを Github Codespaces で動作させることをトライしている内容です。
現時点では少しつまずくポイントがありますが、これをアウトプットすることでこれから試す方がつまずくポイントが減れば良いなと思っています。
結論を先に
- Rails アプリケーションを Github Codespaces で動かすには
--devcontainer
オプションをつけたrails new
の構成でおおよそ動く。が、いくつか注意点がある。 - codespace でなくても必要な一般的な注意点
-
localhost
ではないドメイン名でのアクセスになるので、config.hosts
の調整を要する
-
- codespace 独自の問題 (2025/04/30 時点)
- POST リクエストが処理できない
- HTTP Origin ヘッダによるサイトのオリジンチェックにひっかかるので
config.action_controller.forgery_protection_origin_check
をfalse
に指定する必要がある
- HTTP Origin ヘッダによるサイトのオリジンチェックにひっかかるので
- 初期状態で GitHub Codespaces のポートフォワーディングが効かない
- 以下いずれかのワークアラウンドを要する
- ポートの公開範囲を、初期値の Private から ⇒ Public ⇒ Private と動かすとなぜか Private アクセス (自分だけアクセス可) が機能する
- docker image を Rails 提供のものから microsoft 提供のものに差し替える
-
.devcontainer/devcontainer.json
の設定、forwardPorts
を無効化する
- 以下いずれかのワークアラウンドを要する
- POST リクエストが処理できない
GitHub Codespaces とは
github が提供しているクラウドベースの開発環境です。
ブラウザひとつで開発を始められる環境です。
ブラウザ版の VS Code (github.dev) は基本的にエディタだけであり、実際にアプリケーションを動作させる環境が揃うわけではありません。一方 Github Codespaces はエディタだけではなくアプリケーションを動作させる環境がちゃんと動きます。
GitHub のユーザに対し、 15 GB/月 ストレージ および 120コア時間の無料枠が用意されています。また、 GitHub Pro ユーザの場合は 20 GB/月 ストレージ および 180コア時間です。
また、codespace は30分放置でアイドルに、30日放置で削除されます。この時間は設定 https://github.com/settings/codespaces で変更可能です。
Rails アプリケーションを Github Codespaces で動かす
--devcontainer
オプション
Rails アプリケーションを新しく用意するためのコマンド rails new
には --devcontainer
というオプションがあります。
このオプションをつけて実行すると、 .devcontainer/
ディレクトリのもとにいくつかのファイルが作成されています。
$ rails new sample --devcontainer
$ cd sample/
$ ls .devcontainer/
compose.yaml devcontainer.json Dockerfile
これらが作成されることにより、 VS Code の dev container で開発環境を開くことができるようになります。
ここでは詳細は省略しますが、 GitHub Codespaces での起動でもこの構成を使います。
GitHub Codespaces で開いてみる
一度 rails new を実施した状態から first commit を入れて GitHub のリポジトリに push します。
その後、 https://codespaces.new/OWNER/REPO
の URL にアクセスすることで Github Codespaces での起動を確認する画面が表示されます
また、余談ですが README.md
に以下のような記述を入れることでリンクを配置することもできます。
[](https://codespaces.new/OWNER/REPO)
以下のような表示になります。
codespace 上での操作
起動してしばらく放置していると、 bin/setup --skip-server
がコンソール上で実行されます。
これは、 --devcontainer
オプションをつけて rails new
したことで作成されるファイルを見るとこの設定の記述が確認できると思います。
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "bin/setup --skip-server"
setup を終えたら、コンソールから rails s
で起動できます。
rails s
。。。 が、実はまだアクセスできません。もう少し続きます。
codespace でのポート転送の設定についての課題
GitHub Codespaces には、 codespace の中で動かす Rails サーバの http://localhost:3000
に対して外部からアクセス可能にするポートフォワーディングの仕組みがあります。
既定で、ポートの表示範囲に Private が設定されているのですがこの場合は自身のアカウントで GitHub にログイン状態であれば直接ブラウザからアクセスできます。
。。。が、現時点では初期状態からなんらかの変更をしないとなぜかアクセスできません。
既定が Private なので Private を維持した状態でアクセスするためには Private -> Public -> Private と変更する必要があります。
手動トグル以外の回避策
上記のとおり、ポートの公開範囲を Private -> Public -> Private といった変更をすることで本来の公開範囲 Private として動きます。
この操作で困らない場合はそれで良いですが、起動したらすぐに公開範囲が正しく作用して欲しい場合は以下の方法があります。
(しかし、これらは rails new
してすぐに codespace で開発を始められるかという観点からあまり好ましくはないなと考えているので今後改善されれば良いなと思います。)
Docker イメージを差し替え
rails new --devcontainer
オプションを実行することで生成される devcontainer に関する設定ですが、そこで以下の記述があります。
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.4.2
FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
Docker イメージとして https://github.com/rails/devcontainer の ghcr.io/rails/devcontainer/images/ruby
が使われていますが、これを microsoft が提供している ruby の Docker イメージ mcr.microsoft.com/devcontainers/ruby
と差し替えます。
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.4.2
+FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
-FROM mcr.microsoft.com/devcontainers/ruby:3.4
すると、本件のポート転送に関する問題は回避でき、はじめから Private のポート転送の設定が効いた状態で始められます。
forwardPorts
を削除
--devcontainer
オプションを付けて rails new
した .devcontainer/devcontainer.json
に、以下の記述が存在しています。
コンテナ内で開いているポートをホストマシン側に自動で転送するための設定項目なのですがこれを無効し、実際に 3000番ポートが使われる際の自動検出に頼るようにすれば Private のポート転送の設定が効いた状態で始められます。
// Use 'forwardPorts' to make a list of ports inside the container available locally.
- "forwardPorts": [3000],
+ // "forwardPorts": [3000],
Blocked hosts エラーを解決する
この状態でブラウザからアクセスすると、エラーが生じます。
Blocked hosts: symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev
To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
config.hosts << "symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev"
For more details view: the Host Authorization guide
これを解決するには、表示されているように config.hosts
にホスト名を加える必要があります。
GitHub Codespaces で実行する際に設定されている環境変数を使います。
Rails.application.configure do
if ENV["CODESPACES"] == "true"
# 以下は codespace のドメインを hosts に加えています。
# 別解として、面倒であれば config.hosts.clear してしまうという手もあります。
#
codespaces_port_forwarding_domain = ENV["GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"]
codespace_name = ENV["CODESPACE_NAME"]
host = "#{codespace_name}-3000.#{codespaces_port_forwarding_domain}"
config.hosts << host
end
# 省略...
end
config/environments/development.rb
を修正後、起動させている rails s
を一度止めて再度動かし、
改めてブラウザでアクセスすると無事アクセスできます。
POST リクエストが処理できない
上記までの手順で、 GitHub Codespaces で Rails アプリケーションが動作します。
が、実はまだ GET リクエストだけしか処理できず、 POST リクエストはエラーになります。フォームを使った機能などを作るとこの問題にあたることになります。
ActionController::InvalidAuthenticityToken (HTTP Origin header (http://localhost:3000) didn't match request.base_url (https://symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev)):
これは実際のリクエストの URL に対し、 Http Origin Header の内容がアンマッチゆえに生じているものです。
(ruby) request.base_url
"https://symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev"
(ruby) request.origin
"http://localhost:3000"
(rdbg)
しかしながら、ブラウザからはたしかに Origin Header は現在アクセス中のドメインに基づいた値が送出されています。
これは、どうやら GitHub Codespaces がポートを外部解放するための間に存在するネットワークの中で Origin ヘッダが書き換えられていると思われます。
本件については、レポートしてみているので今後状況が変わるかもしれません。 (状況が変われば本記事もアップデートします)
GitHub Codespaces での環境に限り POST リクエストが処理できるようにする
このチェックは、 Rails のアプリケーション設定値 config.action_controller.forgery_protection_origin_check
により動作しています。
3.9.8 config.action_controller.forgery_protection_origin_check
CSRFの追加対策として、HTTPのOriginヘッダーがサイトのoriginと一致することをチェックすべきかどうかを設定します。
本来は既定値を可能な限り尊重したいのですが、 GitHub Codespaces で動作させる場合にこの設定値を無効化するように調整しました。
Rails.application.configure do
if ENV["CODESPACES"]
codespaces_port_forwarding_domain = ENV["GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"]
codespace_name = ENV["CODESPACE_NAME"]
host = "#{codespace_name}-3000.#{codespaces_port_forwarding_domain}"
config.hosts << host
+
+ warn "Disabling the CSRF protection Origin header check in GitHub Codespaces"
+ config.action_controller.forgery_protection_origin_check = false
end
これにより、 POST リクエストについても期待どおり動作するようにできました!
まとめ & 宣伝
ブラウザ上で開発環境を気軽に体験できるサンプルアプリケーションの環境として Github Codespaces は良い選択だと思います。当然そのまま実行もできます。
Rails アプリケーションを動かすためには前述のとおりいくつかの調整が必要でした。また、ポートフォワーディングの設定に気をつける点がありますがワークアラウンドもあります。
関連した宣伝ですが、 Rails で複数の ActiveRecord モデルを内包し、あたかもそれがひとつのモデルであるように振る舞うことことを提供する active_record_compose という gem を作成しています。
これを、実際に GitHub Codespaces 上で試すためのサンプルアプリケーション環境を用意しているのでよければさわってみてください。日本語 README も用意しています。
また、この gem そのものについては以下に記事をおいています。
Discussion