jsを触る機会が増えてきたので、Dockerを使って環境構築の練習中です。
いろいろ手探りでやってみた結果、一応、dev環境は動くようになった。
docker, rails, mysql, skip-javascript, skip-turbolinks, webpackの環境構築
ファイル全体は、 https://github.com/kkosuke/2022-04-14-rails-demo を参照してください。
rails
任意のディレクトリ内で…
rails-demo $ touch {Dockerfile,docker-compose.yml,Gemfile,Gemfile.lock,entrypoint.sh}
docker-compose.yml
version: '3'
services:
demo_db:
container_name: demo_db
image: mysql:5.7
environment:
MYSQL_DATABASE: root
MYSQL_ROOT_PASSWORD: password
ports:
- "13397:3306"
volumes:
- ./tmp/db:/var/lib/mysql
demo:
container_name: demo
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/demo
ports:
- "3000:3000"
depends_on:
- demo_db
Dockerfile
FROM ruby:2.7.5
# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn
RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN mkdir /demo
WORKDIR /demo
COPY Gemfile /demo/Gemfile
COPY Gemfile.lock /demo/Gemfile.lock
RUN bundle install
COPY . /demo
RUN yarn install --check-files
# コンテナ起動時に実行させるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
entrypoint.sh
#!/bin/bash
set -e
rm -f /demo/tmp/pids/server.pid
exec "$@"
Gemfile
source 'https://rubygems.org'
gem 'rails', "~> 7.0.2"
build と rails new
rails-demo $ docker-compose build --no-cache
<略>
rails-demo $ docker-compose run demo rails new . --no-deps --database=mysql --skip-javascript --skip-turbolinks
<略>
config/database.yml
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:
host: localhost
development:
<<: *default
database: demo_development
host: demo_db
username: root
password: password
test:
<<: *default
database: demo_test
host: demo_db
username: root
password: password
db:create
rails-demo $ docker-compose run demo rails db:create
[+] Running 1/0
⠿ Container demo_db Running 0.0s
Could not find public_suffix-4.0.7 in any of the sources
Run `bundle install` to install missing gems.
rails-demo $ docker-compose build --no-cache
<略>
rails-demo $ docker-compose run demo rails db:create
[+] Running 1/0
⠿ Container demo_db Running
Created database 'demo_development'
Created database 'demo_test'
挙動確認(動いた)
rails-demo $ docker-compose up
webpack
yarnでいろいろ
rails-demo $ docker-compose run demo yarn add webpack webpack-cli webpack-remove-empty-scripts
rails-demo $ docker-compose run demo yarn add @babel/cli @babel/core @babel/polyfill @babel/preset-env babel-loader
rails-demo $ docker-compose run demo yarn add autoprefixer core-js css-loader file-loader mini-css-extract-plugin postcss postcss-loader sass sass-loader
asset まわり にディレクトリとかファイルを生成
app/assets/_dev/js/
app/assets/_dev/style/application.scss
app/assets/builds/
webpack.config.js
const path = require("path");
const webpack = require("webpack");
const glob = require("glob"); //globで、ワイルドカードを使ったファイル名特定を使う。
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // jsがcssを読み込んでいる場合、cssを切り出して出力
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts'); // 空のjsファイルを消す
const mode = process.env.NODE_ENV === 'development' ? 'development' : 'production';
// const enabledSourceMap = mode === "development";
const enabledSourceMap = false;
const devPath = './app/assets/_dev/';
// -----------------------------
// entryのobject生成
// -----------------------------
const directory = {
"js": ["js"],
"style": ["scss","css"],
};
const entries = {};
for (let key in directory) {
directory[key].forEach(extension =>{
glob.sync(`**/*.${extension}`,{
cwd: `${devPath}${key}/`,
ignore: '**/_*',
}).map(fileName => {
const ext = new RegExp( `.${extension}$`);
const fileNameExceptExt = fileName.replace(ext, '');
const filePath = path.resolve(`${devPath}${key}/`, fileName);
if (entries[fileNameExceptExt]) {
entries[fileNameExceptExt].push(filePath);
} else {
entries[fileNameExceptExt] = [filePath];
}
});
});
}
module.exports = {
mode: mode,
devtool: false,
entry: entries,
output: {
filename: "[name].js",
sourceMapFilename: "[name].js.map",
path: path.resolve(__dirname, "app/assets/builds"),
},
plugins: [
new RemoveEmptyScriptsPlugin(),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
}),
new webpack.SourceMapDevToolPlugin({}),
new MiniCssExtractPlugin({}),
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
'corejs': 3 // 参考: https://qiita.com/riversun/items/63c5f08c8da604c5ec1a
}
]
]
}
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
url: false,
sourceMap: enabledSourceMap,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
sourceMap: enabledSourceMap,
postcssOptions: {
plugins: [
require('autoprefixer')({
grid: true
}),
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: enabledSourceMap,
},
},
],
},
{
test: /\.(png|jpe?g|gif|eot|woff2|woff|ttf|svg)$/i,
use: 'file-loader'
},
]
},
resolve: {
extensions: [
'.js',
'.scss', '.css',
'.jpg', '.png', '.gif',
'.woff', '.woff2', '.svg', '.ttf', '.eot',
' '
],
},
}
manifest.js
//= link_tree ../images
//= link_tree ../builds
bin/dev
#!/usr/bin/env bash
if ! command -v foreman &> /dev/null
then
echo "Installing foreman..."
gem install foreman
fi
foreman start -f Procfile.dev "$@"
Procfile.dev
web: rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'
js: yarn dev
docker-compose.yml
- command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
+ command: bash -c "./bin/dev"
Gemfile
gem "sassc-rails"
gem 'jsbundling-rails'
routes.rb
Rails.application.routes.draw do
root "top#index"
end
app/views/top/index.html.erb
<div>
app/views/top/index.html.erb
</div>
app/controllers/top_controller.rb
class TopController < ApplicationController
def index
end
end
package.json 末尾に追加
+ "scripts": {
+ "dev": "webpack --mode development --watch",
+ "build": "webpack --mode production"
+ }
}
gem を bundle installするため、 build し直す
rails-demo $ docker-compose build --no-cache
<結構待つ…>
挙動確認(動かない)
rails-demo $ docker-compose up
<略>
demo | bash: ./bin/dev: /usr/bin/env: bad interpreter: Permission denied
権限がおかしいので、
$ ls bin/dev
-rw-r--r--
$ chmod -R 755 bin/dev
$ ls bin/dev
-rwxr-xr-x
$ docker-compose build
<略>
$ docker-compose up
挙動確認(動いた)
rails-demo $ docker-compose up
参考
https://tmasuyama1114.com/docker-compose-rails6-mysql-development/
https://qiita.com/geek_shanshan/items/8f348734d95d9ece9576
課題
分からないことが多すぎる。
ないないだらけな私ですが、どなたか知見ある方がいれば、いろいろ教えてほしいです。
- 環境構築ほんと苦手です。
- このコードは本番環境を全く想定できていない。
-
docker-compose.yml
は、これだけじゃ不十分な気がする。 -
Dockerfile
も、docker-compose.yml
の工夫の余地はあると思うが、どこから手をつけたらいいか分からない。 -
entrypoint.sh
ってなに? -
manifest.js
ってなに? -
app/assets
を 完全廃止して、webpackで管理したいけど、sprockets-rails
が よくわからない。 - cssの背景画像やfontをどこにどう置くか、全然想定できていない。
- controllerやaction別でいい感じにjs,cssを吐き出す仕組みはないだろうか。…それがVueを採用する理由かしら。
- Dockerの設定がよくわからないから、 参考記事の
webpack-dev-server
の設定が理解できない。 -
docker-compose build --no-cache
をするタイミングが、よくわからない。bundle install
をし直したいタイミングでいいのかな。 -
package.json
は 全てdependencies
でいいのか。 - 環境構築とDockerとRailsとVueとSQLとか学びたい。