How to Run a Rails Application on GitHub Codespaces

In this article, I’ll guide you through my experience running a Rails application on GitHub Codespaces. Although there are still a few hurdles to overcome, I hope that by sharing the issues I encountered and how I addressed them, others can have a smoother experience when trying it themselves. Summary First To run a Rails application on GitHub Codespaces, using rails new with the --devcontainer option generally works, but there are a few caveats. General caveats (not specific to Codespaces): Since the access will be through a domain name rather than localhost, you need to adjust config.hosts. Codespaces-specific issues (as of 2025/04/29): POST requests cannot be processed. The application fails the origin check based on the HTTP Origin header, so you need to set config.action_controller.forgery_protection_origin_check to false. Port forwarding in GitHub Codespaces does not work by default. You need to apply one of the following workarounds: Change the port visibility from Private → Public → Private. For some reason, switching back enables Private access (accessible only by yourself). Replace the docker image from the Rails-provided one to a Microsoft-provided image. Disable the forwardPorts setting in .devcontainer/devcontainer.json. What is GitHub Codespaces? GitHub Codespaces is a cloud-based development environment provided by GitHub. https://github.com/features/codespaces It allows you to start developing with just a browser. Note that the browser-based VS Code (github.dev) is mainly a code editor and does not provide a full runtime environment for applications. In contrast, GitHub Codespaces offers not only an editor but also a complete environment where you can run applications. GitHub users are provided with a free monthly allowance of 15 GB storage and 120 core hours. GitHub Pro users receive 20 GB storage and 180 core hours per month. Additionally, a codespace becomes idle after 30 minutes of inactivity and is deleted after 30 days of inactivity. You can change these timeout settings at: https://github.com/settings/codespaces For more details: https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces Running a Rails Application on GitHub Codespaces The --devcontainer Option The rails new command, which is used to generate a new Rails application, has an option called --devcontainer. When you run rails new with this option, it automatically generates several files under the .devcontainer/ directory. $ rails new sample --devcontainer $ cd sample/ $ ls .devcontainer/ compose.yaml devcontainer.json Dockerfile With these files, you can open the development environment inside a VS Code dev container. Although the detailed explanation of these files is omitted here, you will also use this setup when launching the environment on GitHub Codespaces. Opening the Project in GitHub Codespaces After running rails new, make your first commit and push the code to a GitHub repository. Then, you can access the following URL to open it in GitHub Codespaces: https://codespaces.new/OWNER/REPO You will see a screen confirming that the Codespace is being created. As a side note, you can also add a link directly in your README.md by including the following snippet: [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/OWNER/REPO) This will display a badge like the one below: NOTE: Please replace OWNER and REPO with the appropriate values for your repository. Operations on Codespace After launching the Codespace and waiting a short while, you will notice that bin/setup --skip-server is automatically executed in the console. You can find the setting for this behavior in the files generated when you run rails new with the --devcontainer option. .devcontainer/devcontainer.json // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "bin/setup --skip-server" Once setup is complete, you can start the Rails server manually by running: rails s ...However, you still won't be able to access the application just yet. There's a bit more to do! Issue with Port Forwarding Settings on Codespace GitHub Codespaces provides a port forwarding feature that allows external access to a Rails server running inside the Codespace at http://localhost:3000. You can find more information here: https://docs.github.com/en/codespaces/developing-in-a-codespace/forwarding-ports-in-your-codespace By default, ports are set to Private, which means you can access them directly from your browser as long as you are logged in to GitHub with your account. ...However, currently, you need to make some change before you can actually access it — otherwise, access won't work for some reason. Even though the default setting is Private, to make it work whi

Apr 29, 2025 - 04:11
 0
How to Run a Rails Application on GitHub Codespaces

In this article, I’ll guide you through my experience running a Rails application on GitHub Codespaces.

Although there are still a few hurdles to overcome, I hope that by sharing the issues I encountered and how I addressed them, others can have a smoother experience when trying it themselves.

Summary First

  • To run a Rails application on GitHub Codespaces, using rails new with the --devcontainer option generally works, but there are a few caveats.
  • General caveats (not specific to Codespaces):
    • Since the access will be through a domain name rather than localhost, you need to adjust config.hosts.
  • Codespaces-specific issues (as of 2025/04/29):
    • POST requests cannot be processed.
      • The application fails the origin check based on the HTTP Origin header, so you need to set config.action_controller.forgery_protection_origin_check to false.
    • Port forwarding in GitHub Codespaces does not work by default.
      • You need to apply one of the following workarounds:
        • Change the port visibility from Private → Public → Private. For some reason, switching back enables Private access (accessible only by yourself).
        • Replace the docker image from the Rails-provided one to a Microsoft-provided image.
        • Disable the forwardPorts setting in .devcontainer/devcontainer.json.

What is GitHub Codespaces?

GitHub Codespaces is a cloud-based development environment provided by GitHub.
https://github.com/features/codespaces

It allows you to start developing with just a browser.
Note that the browser-based VS Code (github.dev) is mainly a code editor and does not provide a full runtime environment for applications. In contrast, GitHub Codespaces offers not only an editor but also a complete environment where you can run applications.

GitHub users are provided with a free monthly allowance of 15 GB storage and 120 core hours.
GitHub Pro users receive 20 GB storage and 180 core hours per month.

Additionally, a codespace becomes idle after 30 minutes of inactivity and is deleted after 30 days of inactivity.
You can change these timeout settings at: https://github.com/settings/codespaces

For more details:
https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces

Running a Rails Application on GitHub Codespaces

The --devcontainer Option

The rails new command, which is used to generate a new Rails application, has an option called --devcontainer.
When you run rails new with this option, it automatically generates several files under the .devcontainer/ directory.

$ rails new sample --devcontainer
$ cd sample/
$ ls .devcontainer/
compose.yaml  devcontainer.json  Dockerfile

With these files, you can open the development environment inside a VS Code dev container.
Although the detailed explanation of these files is omitted here, you will also use this setup when launching the environment on GitHub Codespaces.

Opening the Project in GitHub Codespaces

After running rails new, make your first commit and push the code to a GitHub repository.
Then, you can access the following URL to open it in GitHub Codespaces:

https://codespaces.new/OWNER/REPO

You will see a screen confirming that the Codespace is being created.
As a side note, you can also add a link directly in your README.md by including the following snippet:

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/OWNER/REPO)

This will display a badge like the one below:

Open in GitHub Codespaces

NOTE: Please replace OWNER and REPO with the appropriate values for your repository.

Operations on Codespace

After launching the Codespace and waiting a short while, you will notice that bin/setup --skip-server is automatically executed in the console.
You can find the setting for this behavior in the files generated when you run rails new with the --devcontainer option.

.devcontainer/devcontainer.json

  // Use 'postCreateCommand' to run commands after the container is created.
  "postCreateCommand": "bin/setup --skip-server"

Once setup is complete, you can start the Rails server manually by running:

rails s

...However, you still won't be able to access the application just yet. There's a bit more to do!

Issue with Port Forwarding Settings on Codespace

GitHub Codespaces provides a port forwarding feature that allows external access to a Rails server running inside the Codespace at http://localhost:3000.

You can find more information here:
https://docs.github.com/en/codespaces/developing-in-a-codespace/forwarding-ports-in-your-codespace

By default, ports are set to Private, which means you can access them directly from your browser as long as you are logged in to GitHub with your account.
...However, currently, you need to make some change before you can actually access it — otherwise, access won't work for some reason.
Even though the default setting is Private, to make it work while keeping it Private, you need to manually change it to Public and then back to Private.

NOTE:
I have reported this behavior — where port forwarding does not work unless a manual change is made — in the following discussions:

Depending on how this issue is resolved, this workaround may become unnecessary in the future.

Workarounds Other Than Manual Toggling

As mentioned above, by manually changing the port visibility from PrivatePublicPrivate, port forwarding will function properly while maintaining the intended Private setting.
If you don't mind doing this manually, that's fine. However, if you want the port visibility to work correctly immediately after startup, there are a few other methods available.

(That said, from the perspective of "being able to start developing right after running rails new and opening a Codespace," I personally think these methods are not ideal. I hope this situation will improve in the future.)

Replacing the Docker Image

When you run the rails new --devcontainer command, it generates a devcontainer configuration with the following content:

.devcontainer/Dockerfile

# 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

By default, the Docker image used is ghcr.io/rails/devcontainer/images/ruby, maintained by the Rails team.
You can replace this with the Ruby image provided by Microsoft: mcr.microsoft.com/devcontainers/ruby.
To do so, modify the Dockerfile like this:

.devcontainer/Dockerfile

 # 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

With this change, the port forwarding issue is avoided, and you can start development with proper Private port visibility working out of the box.

Remove forwardPorts

When you run rails new with the --devcontainer option, the generated .devcontainer/devcontainer.json file includes the following line:

This setting automatically forwards the specified ports from the container to the host machine.
However, if you disable this and rely on automatic port detection when port 3000 is actually used, you can avoid the issue and start with a properly functioning Private port forwarding setting.

   // Use 'forwardPorts' to make a list of ports inside the container available locally.
-  "forwardPorts": [3000],
+  // "forwardPorts": [3000],

Solve the "Blocked hosts" Error

At this point, if you try to access the application from your browser, you will encounter an error.

Blocked hosts error

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

To resolve this, as indicated in the error message, you need to add the host to config.hosts.
We will use environment variables set when running in GitHub Codespaces.

config/environments/development.rb


Rails.application.configure do
  if ENV["CODESPACES"] == "true"
    # Add the Codespace domain to the list of allowed hosts.
    # Alternatively, if you prefer simplicity, you could `config.hosts.clear` instead.
    #
    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

  # (Other settings omitted...)
end

After editing config/environments/development.rb, stop the currently running rails s server, restart it, and then refresh your browser.
You should now be able to access the application without issues.

POST Requests Cannot Be Handled

Following the steps so far, your Rails application will run in GitHub Codespaces.
However, at this point, only GET requests are handled successfully - POST requests will still fail.
You will encounter this issue when implementing features that use forms, for example.

ActionController::InvalidAuthenticityToken (HTTP Origin header (http://localhost:3000) didn't match request.base_url (https://symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev)):

This error occurs because the HTTP Origin header does not match the actual request URL.

(ruby) request.base_url
"https://symmetrical-spoon-6vxqqgxx4cr6qq-3000.app.github.dev"
(ruby) request.origin
"http://localhost:3000"
(rdbg)

However, from the browser's perspective, the Origin header is correctly being set based on the currently accessed domain.

Origin header

It seems that somewhere within the network layer that GitHub Codespaces uses to expose ports externally, the Origin header is being rewritten.
I have reported this issue, so the situation might change in the future. (If it does, I will update this article.)
https://github.com/orgs/community/discussions/156532

Allowing POST Requests to Work in GitHub Codespaces

NOTE:
I have reported the issue regarding the rewriting of the Origin header here:
https://github.com/orgs/community/discussions/156532

Depending on how this issue is resolved, the workaround described below might become unnecessary in the future.

The check that causes the error is controlled by the Rails configuration setting config.action_controller.forgery_protection_origin_check.

3.9.8 config.action_controller.forgery_protection_origin_check (Rails Guides)

Configures whether the HTTP Origin header should be checked against the site's origin as an additional CSRF defense.

Ideally, we would like to respect the default value as much as possible.
However, to get Rails applications working in GitHub Codespaces, I adjusted the configuration to disable this setting only when running in Codespaces.

config/environments/development.rb


 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

With this change, POST requests now work as expected!

Summary & Promotion

GitHub Codespaces is a great choice for easily experiencing a sample application development environment directly in your browser.
Of course, you can also use it for actual development.

As explained earlier, several adjustments are needed to run a Rails application smoothly.
Also, you need to be aware of some points regarding port forwarding settings, but there are workable solutions for them.

As a related note, I have created a Ruby gem called active_record_compose,
which provides a way to compose multiple ActiveRecord models and treat them as if they were a single model.

I have prepared a sample application environment to try it out directly on GitHub Codespaces — feel free to check it out!

I also wrote an article about the gem here: