先日書いた、Ruby3 を試そうでは、Docker で Ruby3 を動作させました。
Rails を動かすにあたっては、もう一工夫必要だったのでメモです。
参考
- won won eater - Mac の Docker が遅い原因と対処方法(公式)
- Qiita - docker-compose を爆速にする
- Qiita - Mac の docker が遅いストレスから解放されよう
- stackoverflow - Docker compose port forwarding not working properly
- docker/compose - docker-compose up -d doesn’t expose ports when defined with build directive
- Qiita - Docker のコンテナを起動したままにする
- Qiita - 【Rails6】Docker コンテナを再起動しないとソースコードが反映されない
- Qiita - docker で nuxt.js の環境を作ってみる
- TechRacho - 週刊 Rails ウォッチ(20190930 前編)知られざる 7 つの便利 gem、Duration.build に string を渡せなくなる、Webpacker の packs をマスターほか
- Rails ガイド - アセットパイプライン
- ryotaku’s Tech Blog - Rails が JavaScript やスタイルシートを読み込む仕組み
作るもの
- Docker で Rails を動作する環境構築
- Webpacker は使用しません
環境構築 1 問題あり
Dockerfile
Dockerfile は、Ruby3 を試そうで使用したものに加え、3000 番ポートを解放する設定を追加します。
1 | FROM ruby:3.0.0 |
操作
先に示した Dockerfile を用意し、以下の操作で起動します。
1 | # 任意ディレクトリで |
こちらの操作で、Rails が起動できます。http://localhost:3000
にアクセスすると、いつもの楽しい Rails の初期画面が表示されます。
が、遅いです。それはもう、ものすごく。
起動するまでに、30 秒くらいかかります。
この状態で開発を続けるのは、とてもストレスフル。
他にも行っていないこととして、データベースが SQLite のままになっているなどの問題があるので、次の章で修正します。
環境構築 2 問題を解決
Docker-compose.yml
1 | version: "3" |
操作
1 | docker-compose build |
こちらの操作で、Rails が 「高速に」 起動できます。http://localhost:3000
にアクセスすると、いつもの楽しい Rails の初期画面が表示されます。
データベースを MYSQL に変更
MYSQL もコンテナで用意する例も見かけますが、rbenv の代わりに ruby のバージョン管理代わりに Docker を使う目的なので、
MYSQL 自体はホストマシンで立ち上げます。
Gemfile に以下を追記して、bundle install
します。
1 | gem 'mysql2' |
config/database.yml を以下のように書き換えます。
ポイントは、ホスト指定のhost.docker.internal
です。この指定で、ホストマシンのローカルを指定できます。
1 | default: |
config/database.yml を編集し、以下コマンドでホストマシンの MYSQL にデータベースの作成ができるようになります。
1 | bundle exec rails db:create |
ファイルの変更が反映されない
普段なら変更した内容を即時反映するはずが、そうならないということが起きたので、調査。
以下の内容を書き換えます。
1 | # もともとはこっち |
ファイルの更新イベントを検知する仕組みがデフォルト設定ですが、どうも Docker でマウントしたドライブ内は検知できないようです。
書き換えると、非 Docker での起動と同様に、即時反映するようになりました。
ページを増やすとエラーになる
API サーバーとして使っていれば問題ないのですが、view を使うと以下のようなエラーを起こします。
1 | ActionView::Template::Error (undefined method `javascript_pack_tag' for #<ActionView::Base:0x00000000007ee0> |
webpacker を使っていないので当然です。<%= javascript_pack_tag ~~~
は削除しておきます。
(webpacker も動くコンテナの作成はまた別途考えたいところです。)
asset pipeline で Javascript を使う
Webpacker を今回は使用しないので asset pipeline で javascript を設定を追加します。
app/assets/config/manifest.js を編集
以下の記述を app/assets/config/manifest.js に追記します。
1 | //= link_directory ../javascripts .js |
JavaScript ファイル本体の設置
app/assets/javascripts ディレクトリを作成し、続けて app/assets/javascripts/application.js を作成します。
1 | //= require_tree |
順番に依存するものがあれば、//= require_tree
よりも前に、//= require hogehoge
のように記述します。
テンプレートでの読み込み
app/views/layouts/application.html.erb に<%= javascript_pack_tag ~~~
を削除していました。
代わりとして<%= javascript_include_tag ~~~
を記述します。
1 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> |
以上で、app/assets/javascripts 以下のファイルを読んでくれます。
ではでは。