想定読者
- Rails のフロントエンド開発に webpack を利用している(利用しようとしている)
- Rails/webpack 自体の設定については、本記事では必要最低限しか記載しません
- ※ webpacker gem 経由で webpack を利用されている場合
- →本記事では webpacker は利用しません。webpack 自体の設定を直接書くことになります。
- Rails 実行用のコンテナと webpack 実行用のコンテナを分離したい&それぞれのコンテナサイズを小さくしたい
- コンテナの再ビルド時間を減らしたい
- Node.js に依存する処理が Rails コード内に存在しないことを簡単に検知したい
- ただの趣味
- etc.
環境
- Ruby >= 2.5.1 (for Rails 6)
- with Bundler
- Node.js >= 12.x
- with Yarn
- Docker
- with Docker Compose
※ 一部手順を簡略化するため、Ruby および Node.js がローカルにもインストールされていることを前提としています
docker run ruby -v .:/app -w /app
などを使えばローカルインストールせずとも構築できるとは思いますが未確認です
手順
必要なパッケージのインストール
Rails new の実行
cd path/to/workspace
gem install rails
rails new <my-new-rails-project> --database=postgresql --skip-sprockets --skip-javascript --skip-turbolinks --skip-bundle --skip-webpack-install
-
<my-new-rails-project>
,--database=
あたりの指定は適宜読み替えてください - css(sass) の管理も webpack に任せる前提となっています。css(sass) の管理を Rails で行いたい場合は
--skip-sprockets
オプションは指定しないでください
Simpacker gem のインストール
cd path/to/workspace/<my-new-rails-project>
echo "gem 'simpacker'" >> Gemfile
bundle install
bundle exec rails simpacker:install
webpack-dev-server のインストール
cd path/to/workspace/<my-new-rails-project>
yarn add -D webpack-dev-server
Dockerfile の作成
for Rails
# <my-new-rails-project>/build/Dockerfile.rails
FROM ruby:2.7.0 as rails-dev
RUN apt-get install -y locales \
&& echo 'ja_JP.UTF-8 UTF-8' >> /etc/locale.gen \
&& locale-gen \
&& update-locale LANG=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
CMD ["bundle" "exec" "rails" "server"]
for webpack
# <my-new-rails-project>/build/Dockerfile.rails
FROM node:12 as webpack
RUN mkdir /app
WORKDIR /app
ADD package.json /app/package.json
ADD yarn.lock /app/yarn.lock
RUN yarn install
CMD ["yarn" "run" "webpack-dev-server" "--config" "webpack.config.js"]
docker-compose.yml
# <my-new-rails-project>/docker-compose.yml
version: '3.7'
services:
rails:
build:
context: .
dockerfile: build/Dockerfile.rails
target: rails-dev
tty: true
stdin_open: true
ports:
- "3000:3000"
volumes:
- .:/app
- bundle:/usr/local/bundle
depends_on:
- db
- webpack
webpack:
build:
context: .
dockerfile: build/Dockerfile.webpack
target: webpack
ports:
- "3035:3035"
volumes:
- .:/app
- node_modules:/app/node_modules
db:
image: postgres:12
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- pg_data:/var/lib/postgresql/data
volumes:
bundle: {}
node_modules: {}
pg_data: {}
Rails/webpack それぞれの設定を変更
Rails
config/puma.rb
docker コンテナ外からアクセスするために、listen address を 127.0.0.1
から 0.0.0.0
に変更します
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
-port ENV.fetch('PORT') { 3000 }
+port ENV.fetch('PORT') { 3000 }, '0.0.0.0'
# Specifies the `environment` that Puma will run in.
#
config/database.yml
db
コンテナに接続する例です(適宜読み替えてください)
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ username: postgres
+ password: postgres
+ host: db
development:
<<: *default
webpack.config.js
See also: https://github.com/hokaccha/simpacker/blob/master/example/webpack-dev-server/README.md
output: {
path: path.resolve(__dirname, "public/packs"),
- publicPath: "/packs/",
+ publicPath: isProd ? "/packs/" : "//localhost:3035/packs/",
filename: isProd ? "[name]-[hash].js" : "[name].js"
},
...
},
- plugins: [new WebpackAssetsManifest({ publicPath: true })]
+ plugins: [new WebpackAssetsManifest({ publicPath: true, writeToDisk: true })]
+ devServer: {
+ host: "0.0.0.0",
+ port: 3035,
+ hot: true,
+ headers: {
+ "Access-Control-Allow-Origin": "*"
+ }
+ }
}
動作確認
Rails controller/view の作成
config/routes.rb
Rails.application.routes.draw do
root 'home#index'
end
app/controllers/home_controller.rb
class HomeController < ApplicationController
def index; end
end
app/views/layouts/application.html.slim
doctype html
html[lang="ja"]
head
meta[charset="UTF-8"]
title MyNewRailsProject
= csrf_meta_tags
= csp_meta_tag
= javascript_packs_tag 'application'
body
= yield
app/views/home/index.html.slim
h1 home#index
Rails server の起動
docker-compose build
docker-compose up -d
open http://localhost:3000 # for macOS