🥊

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での環境構築のための知識を獲得したい、今後自分や誰かの役に立つかはわからないけれど、奮闘記を残しておきたいという思いから、この記事を書くことにしました。

記事の構成

  1. 前提
  2. 私が躓いたポイントのまとめ
  3. まとめ(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に流されるがまますぎるのお導きに頼りがちだったことがよくわかりますね

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などが起動できなくなった。
✅ 対処法
  1. ホストのアーキテクチャを確認

    ターミナルで実行
    uname -m
    

    結果がx86_64なら、Dockerでもlinux/amd64を指定。

  2. docker-compose.yml にアーキテクチャを明示

    docker-compose.yml
    services:
      web:
        platform: linux/amd64
    
    • webでもdbでも、アーキテクチャを明示してビルドしなければ高確率でエラーが出ます!
  3. 不要なボリューム/キャッシュを削除

    ターミナルで実行
    docker compose down --volumes --remove-orphans
    docker system prune -a --volumes
    
  4. 明示的に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内で上書きしてしまった
✅ 対処法
  1. 壊れたbinファイルを削除

    ターミナルで実行
    rm -f bin/bundle bin/rails bin/rake
    
  2. 再ビルド

    ターミナルで実行
    docker compose build --no-cache
    
  3. 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 が使用できない。
🧨 原因
  • CMDENTRYPOINTで実行されるスクリプトが空(何もせず終了)。
  • bin/dev が存在しない・実行不可・foremanが未導入。
✅ 対処法
  • DockerfileENTRYPOINT ["bin/dev"] を指定。

  • bin/dev に次のような内容と実行権限を付与:

    bin/dev
    usr/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.yml
    command: 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公式のセットアップスクリプトを使用:

    Dockerfile
    curl -fsSL https://deb.nodesource.com/setup_18.x | bash -
    apt-get install -y nodejs
    npm install -g yarn
    
  • これにより、yarn installnpx tailwindcssが正常動作。


⑧ Tailwind CSS未検出エラーおよび application.tailwind.css が生成されない

🧨 原因
  • tailwindcss のインストールが package.json 上で未定義。また、 npx 自体も未インストールであった。
  • bin/dev を起動しても tailwindcss プロセスが起動せず、CSSが生成されない。
✅ 対処法
  • DockerfileにてNode.jsとYarnのインストール後、yarn add -D tailwindcssを実行。
  • package.jsontailwindcsspostcss, 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依存になっているが、未インストール。
✅ 対処法
  1. watchman を導入(任意):

    Dockerfile
    RUN apt-get install -y watchman
    
  2. あるいは Procfile.dev-watch --poll を併用することで対応

    Procfile.dev
    css: 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 で巻き込んで終了させていた。
✅ 対処法
  1. JSファイルの存在を確認し、必要であれば作成:

    ターミナルで実行
    mkdir -p app/javascript
    echo "console.log('hello');" > app/javascript/application.js
    
  2. Procfile.devjs: 行を修正:

    Procfile.dev
    js: yarn build --watch || sleep 1000000
    

    または:

    Procfile.dev
    js: while true; do yarn build; sleep 3600; done
    
  3. 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.ymldb セクションから DATABASE_HOST を削除

⑬ 「localhost:3000」にアクセスしてもRailsの画面に遷移しない

❓症状
  • https://localhost:3000にアクセスしても、Railsの画面が表示されず、次のようなエラーが発生:

    ブラウザの表示
    localhost からデータが送信されませんでした。
    ERR_EMPTY_RESPONSE
    
🧨 原因 - 1
  • Pumaは証明書設定がない限りHTTPS接続に対応していないため、https://localhost:3000 では接続できない。
✅ 対処法 - 1
  1. アクセスURLを明示的に http://localhost:3000 に変更する。

  2. ブラウザのURLを以下に修正:

    https://localhost:3000  ❌(NG)
    ↓
    http://localhost:3000  ✅(OK)
    
  3. ページが表示されるか確認。HTTPSのブックマークやオートコンプリートは削除・無効化すること。


🧨 原因 - 2
  • Pumaが 127.0.0.1 のみでバインドしていると、DockerやWSLホストからの接続を受け付けないケースがある。
✅ 対処法 - 2
  1. Procfile.dev または bin/dev のWebサーバー起動行を次のように修正:

    Procfile.dev
    web: rm -f tmp/pids/server.pid && bin/rails server -b 0.0.0.0 -p 3000
    
    • 現在のファイル構成ではこの記載を採用してません
  2. Dockerコンテナを再起動:

    ターミナルで実行
    docker compose down
    docker compose up -d
    
  3. 別ターミナルで bin/dev を実行:

    別のターミナルで実行
    docker compose exec web bin/dev
    

🧨 原因 - 3
  • WSL2 環境では localhost:3000 がWindowsホストからWSL側に適切に転送されないことがある。
  • 特に、明示的なポートプロキシ設定がなければ通信がWSL内に閉じてしまう。
✅ 対処法 - 3
  1. PowerShell(管理者モード)を開いて、以下のコマンドでポートプロキシ設定状況を確認:

    PowerShellで実行
    netsh interface portproxy show all
    
  2. ポート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
    
  3. 設定後、ブラウザで http://localhost:3000 にアクセスすると、WSL内のRailsサーバに接続可能となる。

❕ 備考
  • 上記のうち、解決策①〜③のいずれか一つでも不完全だと、接続は成立しない可能性があるため、順を追ってすべて確認することが重要

3.まとめ

躓きポイントを列挙するだけで、かなりの長文記事になってしまいました!💦

こちらの記事は、Windows(WSL)でRailsの環境構築をしている際にエラーが出たときに、参考にお使いいただければ幸いです

続きの記事では、設定ファイルの内容と構成をそのまま公開しています!
続きの記事は反省文となっております。

⇒続き

Discussion