2025-05-20:Ruby on Rails環境構築のためDockerと5日も闘った記録 ( 1 )
はじめに
RUNTEQ関係者の皆さま、あるいはWindowsでDockerを使用しRuby on Railsの環境構築をしようとしている皆さま、こんにちは。
今回のテーマはタイトルの通りです。
オンラインプログラミングスクール・RUNTEQには2025年5月7日に入学し、5月15日に入門STEPの「Rails入門」に突入しました。
「学習オリエンテーション」の動画を視聴し終え、さて、これから本格的にWebアプリケーション開発の学習が始まるぞ! と意気込んでいました。
その直後に大問題が発生します。
カリキュラムの本編に入る前の「環境構築をしましょう」というページを参考に、Dockerに指示しても、書いてある通りに動かない!
最初は検索したり、ロボらんてくん(スクールのカリキュラムに最適化されたAI Chat機能)を使ってみたりしましたが、解決しそうな気配が全然ない。
結果として、chatGPTを相棒に、総やり取り文字数:約91.5万文字、計5日にわたるDockerとの格闘をする羽目になりました。
記事を書いた目的
5日間、記録によると計36時間ほどDockerとの闘いに時間を割いたため「こんなに時間を取られて悔しい!」という思いが強くありました。
ChatGPTに設定の構成とエラーログを投げては、返ってきた設定修正案を適用して再ビルドし、また躓いては設定とエラーの内容を投げ……を繰り返していました。
ほとんどがChatGPT任せのため、Dockerや環境構築の知識を深めながら徐々に目的を達成できた……とはいえないので、悔しさのような罪悪感のようなものが心にあります。
少しでもDockerでの環境構築のための知識を獲得したい、今後自分や誰かの役に立つかはわからないけれど、奮闘記を残しておきたいという思いから、この記事を書くことにしました。
記事の構成
- 前提
- 私が躓いたポイントのまとめ
- まとめ(2へ続く!)
- この記事は、私とChatGPTとのやり取りのログに基づき、さらにChatGPTに要約してもらった内容をもとに書いています
- 設定ファイルの修正を繰り返しながらChatGPTに質問し改善案を求め、その当時の答えをほぼそのまま載せています
続きの記事(2)にある設定ファイル構成とは異なっている部分が多くあります!- 続きの記事は反省文となりました。
1.前提
- WSLとDockerのインストール・セットアップは済んでいるものとします
- Docker Desktopは使用していません
- 使いやすいだろうことは十分に察せられますが、導入するとPCが重くなる可能性があるとのことなので、未導入できています
使用マシン
- Surface go(初代)
- Windows 11搭載(公式には対応していないが、抜け道を見つけインストールした方々の記事を参考にインストール)
- CPU:Intel® Pentium® CPU 4415Y 1.60GHz
- メモリ:8GB RAM
- ストレージ:SSD 128GB
- グラフィックス:Intel® HD Graphics 615
そもそもスクールの推奨スペック満たしてないやんけ!! というお叱りは甘んじて受けます!
(言い訳:)推奨スペックにかなうノートPCも所持しているのですが、自宅以外の場所で学習することも多く、持ち運びがしやすいSurface goを使い続けたかったのです。何年も使用していて愛着もありますし。
課題(目標)
Windows11搭載のSurface Go端末上でWSL2(Ubuntu)を用いてDocker環境を構築し、Ruby on Rails(MySQL+Tailwind CSS+esbuild)を起動する
- 注意:Tailwind CSSとesbuildは、それぞれCSS、JS用のサーバ?ですが「Rails入門」のカリキュラム本編でこれらを使用するのかどうか、現時点ではわからない状態で記事を書いています
- ChatGPT
に流されるがまますぎるのお導きに頼りがちだったことがよくわかりますね
- ChatGPT
2.躓いたポイントのまとめ
あくまで私が躓いたポイントなので、参考になるものもならないものもあると思います!
こちらの内容は、ほぼ全てChatGPTのおかげでまとめられました。
① exec format error(実行形式エラー)
❓症状
-
以下のエラーが頻発:
ターミナルの表示exec /bin/sh: exec format error exec /usr/local/bin/bundle: exec format error
🧨 原因
- ホスト(WSL/Linux x86_64)と異なるアーキテクチャのイメージ(例:arm64)を使用したことによるバイナリ不整合。
- ホストアーキテクチャとの不一致により、シェルやbundleなどが起動できなくなった。
✅ 対処法
-
ホストのアーキテクチャを確認
ターミナルで実行uname -m結果が
x86_64なら、Dockerでもlinux/amd64を指定。 -
docker-compose.ymlにアーキテクチャを明示docker-compose.ymlservices: web: platform: linux/amd64- webでもdbでも、アーキテクチャを明示してビルドしなければ高確率でエラーが出ます!
-
不要なボリューム/キャッシュを削除
ターミナルで実行docker compose down --volumes --remove-orphans docker system prune -a --volumes -
明示的にamd64で再ビルド
ターミナルで実行docker compose build --no-cache --platform linux/amd64 docker compose up
② bundle: exec format error
❓症状
-
exec /usr/local/bin/bundle: exec format errorでバンドル実行不可。
🧨 原因
- ホスト側の
bin/以下のファイルが壊れており、正常なバイナリをDocker内で上書きしてしまった。
✅ 対処法
-
壊れたbinファイルを削除
ターミナルで実行rm -f bin/bundle bin/rails bin/rake -
再ビルド
ターミナルで実行docker compose build --no-cache -
binスクリプト再生成
ターミナルで実行docker compose run --rm web bundle install docker compose run --rm web bundle exec rails app:update:bin
③ web コンテナが exited with code 0 ですぐ停止
❓症状
- コンテナは一見起動するが、即時停止してしまい
execが使用できない。
🧨 原因
-
CMDやENTRYPOINTで実行されるスクリプトが空(何もせず終了)。 -
bin/devが存在しない・実行不可・foremanが未導入。
✅ 対処法
-
DockerfileにENTRYPOINT ["bin/dev"]を指定。 -
bin/devに次のような内容と実行権限を付与:bin/devusr/bin/env bash set -e exec bin/foreman start -f Procfile.dev -
実行権限の追加:
ターミナルで実行chmod +x bin/dev
④ server.pid のPermissionエラーでRails起動失敗
❓症状
Permission denied @ rb_sysopen - /app/tmp/pids/server.pid
🧨 原因
-
tmp/ディレクトリに書き込み権限がなく、Railsが起動時にPIDを記録できない。
✅ 対処法
-
commandに強制的にrm -fを追加して明示的にPIDを削除:docker-compose.ymlcommand: bash -c "rm -f tmp/pids/server.pid && bin/dev" -
現在の
docker-compose.ymlにこの記載はありません -
Dockerfileの以下の部分で対応していると思われる(推測)Dockerfile# 所有者変更(WSL上の権限エラー回避) RUN chown -R rails:rails /app
⑤ entrypoint.sh 未実行によるPumaのserver.pid残留エラー
🧨 原因
-
entrypoint.shでのrm -f tmp/pids/server.pidの処理が機能していなかった。
✅ 対処法
- Dockerfile内で
ENTRYPOINT ["/usr/bin/entrypoint.sh"]を明示。 -
entrypoint.shに実行権限を付与(chmod +x)。
⑥ bundle install しても bundle コマンドが空のまま
🧨 原因
-
DockerfileでBundlerのバージョンを明示していなかったため、環境に依存した問題が発生。
✅ 対処法
-
RUN gem install bundler -v 2.4.22のようにバージョンを明示。 -
.dockerignoreを用意し、vendor/bundleなどローカルキャッシュをビルドに含めないようにして再ビルドを実行ターミナルで実行(ローカルキャッシュを含めずにビルド)docker-compose build --no-cache
⑦ npx not found およびNode/Yarn周りの依存不備
🧨 原因
- apt経由でNode.jsをインストールした結果、古いバージョンとなっていたため、npxやyarnが動作しなかった。
✅ 対処法
-
Node.js公式のセットアップスクリプトを使用:
Dockerfilecurl -fsSL https://deb.nodesource.com/setup_18.x | bash - apt-get install -y nodejs npm install -g yarn -
これにより、
yarn installやnpx tailwindcssが正常動作。
⑧ Tailwind CSS未検出エラーおよび application.tailwind.css が生成されない
🧨 原因
-
tailwindcssのインストールがpackage.json上で未定義。また、npx自体も未インストールであった。 -
bin/devを起動してもtailwindcssプロセスが起動せず、CSSが生成されない。
✅ 対処法
- DockerfileにてNode.jsとYarnのインストール後、
yarn add -D tailwindcssを実行。 -
package.jsonにtailwindcssとpostcss,autoprefixerを追記し、npx tailwindcss initで設定ファイルを作成。 -
bin/devに明示的にyarn build:css --watchを含めたマルチプロセス起動を設定。
⑨ Tailwind CSSが生成されない、watchman: not found
❓症状
-
tailwindcssが変更を検知せず終了、またはwatchman: not found
css.1 | sh: 1: watchman: not found
🧨 原因
-
tailwindcss --watchはデフォルトでwatchmanを使用しようとするが、Docker環境に watchman が未インストール。- Tailwindの監視方式のデフォルトがwatchman依存になっているが、未インストール。
✅ 対処法
-
watchmanを導入(任意):DockerfileRUN apt-get install -y watchman -
あるいは
Procfile.devで-watch --pollを併用することで対応Procfile.devcss: tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --watch --pollこれにより
watchmanがなくても安定動作する
⑩ js.1 exited with code 0 によりForeman全体終了
❓症状
-
js.1 exited with code 0のあとに全プロセスがSIGTERMで落ちる。
🧨 原因
-
esbuildの-watch対象にファイルが存在せず、即終了。
✅ 対処法
-
app/javascript配下にダミーでも良いのでJSファイルを作成:ターミナルで実行touch app/javascript/application.js -
package.jsonのスクリプトが以下のように-watch指定されていることを確認:package.json"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch"
⑪ esbuild の -watch が即終了し、js.1 exited with code 0 により Foreman 全体が落ちる
❓症状
js.1 | Done in 0.39s.
js.1 | exited with code 0
system | sending SIGTERM to all processes
🧨 原因
-
app/javascript/配下に.jsファイルが存在しない、またはwatch対象の書き方が間違っていた。 -
esbuildがビルド後すぐに終了し、常駐しないためforemanが全プロセスをSIGTERMで巻き込んで終了させていた。
✅ 対処法
-
JSファイルの存在を確認し、必要であれば作成:
ターミナルで実行mkdir -p app/javascript echo "console.log('hello');" > app/javascript/application.js -
Procfile.devのjs:行を修正:Procfile.devjs: yarn build --watch || sleep 1000000または:
Procfile.devjs: while true; do yarn build; sleep 3600; done -
package.jsonに適切なスクリプトがあるか確認:package.json"scripts": { "build": "esbuild app/javascript/application.js --bundle --sourcemap --outdir=app/assets/builds --public-path=assets" }
⑫ MySQLコンテナの exec format error および bad array subscript
❓症状
- MySQL起動時に
/usr/local/bin/docker-entrypoint.sh: line 173: ['']='1': bad array subscript
🧨 原因
-
dbサービスにDATABASE_HOSTなど不要な環境変数を与えていた。
✅ 対処法
-
docker-compose.ymlのdbセクションからDATABASE_HOSTを削除
⑬ 「localhost:3000」にアクセスしてもRailsの画面に遷移しない
❓症状
-
https://localhost:3000にアクセスしても、Railsの画面が表示されず、次のようなエラーが発生:
ブラウザの表示localhost からデータが送信されませんでした。 ERR_EMPTY_RESPONSE
🧨 原因 - 1
- Pumaは証明書設定がない限りHTTPS接続に対応していないため、
https://localhost:3000では接続できない。
✅ 対処法 - 1
-
アクセスURLを明示的に
http://localhost:3000に変更する。 -
ブラウザのURLを以下に修正:
https://localhost:3000 ❌(NG) ↓ http://localhost:3000 ✅(OK) -
ページが表示されるか確認。HTTPSのブックマークやオートコンプリートは削除・無効化すること。
🧨 原因 - 2
- Pumaが
127.0.0.1のみでバインドしていると、DockerやWSLホストからの接続を受け付けないケースがある。
✅ 対処法 - 2
-
Procfile.devまたはbin/devのWebサーバー起動行を次のように修正:Procfile.devweb: rm -f tmp/pids/server.pid && bin/rails server -b 0.0.0.0 -p 3000- 現在のファイル構成ではこの記載を採用してません
-
Dockerコンテナを再起動:
ターミナルで実行docker compose down docker compose up -d -
別ターミナルで
bin/devを実行:別のターミナルで実行docker compose exec web bin/dev
🧨 原因 - 3
- WSL2 環境では
localhost:3000がWindowsホストからWSL側に適切に転送されないことがある。 - 特に、明示的なポートプロキシ設定がなければ通信がWSL内に閉じてしまう。
✅ 対処法 - 3
-
PowerShell(管理者モード)を開いて、以下のコマンドでポートプロキシ設定状況を確認:
PowerShellで実行netsh interface portproxy show all -
ポート3000に対するプロキシ設定がない場合は、WSL側のIPを取得し、以下のコマンドで転送を設定:
ターミナルで実行ip addr | grep eth0例:WSL IPが
172.24.176.1の場合PowerShellで実行netsh interface portproxy add v4tov4 listenport=3000 listenaddress=127.0.0.1 connectport=3000 connectaddress=172.24.176.1 -
設定後、ブラウザで
http://localhost:3000にアクセスすると、WSL内のRailsサーバに接続可能となる。
❕ 備考
- 上記のうち、解決策①〜③のいずれか一つでも不完全だと、接続は成立しない可能性があるため、順を追ってすべて確認することが重要
3.まとめ
躓きポイントを列挙するだけで、かなりの長文記事になってしまいました!💦
こちらの記事は、Windows(WSL)でRailsの環境構築をしている際にエラーが出たときに、参考にお使いいただければ幸いです。
続きの記事では、設定ファイルの内容と構成をそのまま公開しています!
続きの記事は反省文となっております。
Discussion