##はじめに
Dockerを用いてRails,Vue,Posgre環境下で開発したいなと思った時に、
Rails,Vueの環境作りに手こずりましたので自分のメモとして保存します。
##この記事で分かること
・Rails6とVueとPostgresのDocker環境が構築できる
・RailsとVueの連動ができる
・PryにてインスタンスとDBの操作ができる
##環境
MacOS Mojave
Ruby 2.6.4
Rails 6.0.3.3
Vue 2.6.12
Webpack 4.44.2
yarn 1.22.5
Docker 2.3.0.5
VScode
##Githubのリンク
僕のGithubのDocker-Start-Kitです。よろしければご活用ください。
Whiro0501/Docker_Rails6_Vue
##Docker環境をMacに構築
ターミナルを開く
mkdirで任意の名前のディレクトリを作成
cdで作成したディレクトリに移動
code.でVScodeを開く
mkdir qiita
cd qiita
code .
VScodeが起動
VScode上のターミナルで作業していくので
ターミナルが起動していなければ⬆︎+Control+@でターミナルを開く
VScodeのターミナル上で以下コマンドを入力してリモートリポジトリのファイルをローカルにコピー
git clone https://github.com/Whiro0501/Docker_Rails6_Vue.git
cdでDocker_Rails6_Vue/ディレクトリに移動
cd Docker_Rails6_Vue/
以下コマンドを実行してDockerイメージをビルド
docker-compose build
以下を実行して、必要なノードモジュールを取得
docker-compose run web yarn install --check-files
以下を実行して DB(Postgres)を作成
docker-compose run web rake db:create
別のターミナルを開く
以下を実行してレールズアプリケーションを起動
#別ターミナルが億劫なら、docker-compose up -dでも良い
docker-compose up
さらに別のターミナルを開く
Viewを更新するたび毎回コンパイルが発生し、時間がかかるため以下を実行
docker-compose exec web ./bin/webpack-dev-server
Webブラウザで以下にアクセス
http://localhost:3000
Railsアプリケーションが起動することを確認
#VueとRailsの連動ってどうやるの?
初期構築時点ではRailsとVueが連動されておりませんので連動させていく。
以下でhomeコントローラを作成する(コントローラー名はなんでも良い)。
docker-compose exec web rails g controller home index
index.html.erbが作成
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
以下ファイルに"root to: 'home#index'"を追加
Rails.application.routes.draw do
root to: 'home#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
Webブラウザで以下にアクセス
http://localhost:3000
まずはindex.html.erbに記述されている内容が表示
Rails側で下地ができたので、次にVueとの連動の設定
app.vueの初期設定
<template>
<div id="app">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
data: function () {
return {
message: "Hello Vue!"
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: center;
}
</style>
hello_vue.jsの初期設定
import Vue from 'vue'
import App from '../app.vue'
document.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
render: h => h(App)
}).$mount()
document.body.appendChild(app.$el)
console.log(app)
})
app.vueが単一ファイルコンポーネントであり、
hello_vue.jsにオブジェクトとして渡される。
それをindex.html.erbに表示させるよう設定する。
index.html.erbを以下の通り設定
<h1>Home#index</h1>
<p>Find me in app/views/home/index.html.erb</p>
<%= javascript_pack_tag 'hello_vue.js' %>
<%= stylesheet_pack_tag 'hello_vue.js' %>
Webブラウザで以下にアクセス
http://localhost:3000
Vueとの連動が完了!!
##Githubののファイルの説明
Whiro0501/Docker_Rails6_Vue
まず上記リンクのGithubの状態から説明する
端的に説明すると以下2つを設定した後の状態となる
従ってRails6とVueとPostgresが使用できる環境を整えることができるという理屈である。
docker-compose run web rails new . --force --database=postgresql --webpack=vue
加えて上記の状態だとPostgresがうまくRailsと連動できないため以下のように設定する。
こちらも公式ドキュメントを参考とした。
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: password
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
production:
<<: *default
database: myapp_production
username: myapp
password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
###Dockerfile
公式ドキュメントのベストプラクティスを参照にした。
DockerはFROM, RUN, COPY毎にレイヤーが作成されるため
RUNやCOPYはできるだけまとめると少ないレイヤーで収めることができるとのこと。
FROM ruby:2.6
# `apt-get install yarn`とするとエラーになる
# プロジェクトに必要なツールをインストール
# &&で繋げてコマンドを実行することによりレイヤーを1つとする
#apt-get update と apt-get installは同一RUN上で行う(分けると最新版を使用できない)
#RUNはイメージの作成次に実行(CMDはコンテナ起動時に実行)
RUN 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 -qq && apt-get install -y nodejs postgresql-client vim && \
apt-get install -y yarn
# ディレクトリの作成
RUN mkdir /myapp
# 作業ディレクトリの指定
#RUN , COPY, ADD 命令のみレイヤを作成するためWORKDIRは気にしなくて良い
# 絶対パスとする
WORKDIR /myapp
# Gemfileが更新された時のみ、レイヤを再構築
#先にプロジェクト全体をコピーしないのはレイヤーを分けるため
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
# ライブラリの依存関係をインストール
RUN bundle install
# プロジェクト全体をコピー(Gemfile/Gemfile.lockはコピーされない)
COPY . /myapp
#コンテナを起動する毎に実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
#コンテナの公開ポート番号の指定
EXPOSE 3000
#指定しなければコンテナ起動時にデフォルトで実行する処理
#Dockerfile では CMD 命令を 1 つしか記述できない
#ENTRYPOINT 命令に対するデフォルト引数としてCMDを使用可能
CMD ["rails", "server", "-b", "0.0.0.0"]
###docker-compose
docker-compose.ymlもDocker公式ドキュメントを参考にした。
version: '3'
services:
db:
# DBにpostgresを使用
image: postgres
# ホストの./tmp/dbと/var/lib/postgresql/dataを同期させる
volumes:
- ./tmp/db:/var/lib/postgresql/data
# 環境変数の指定
environment:
POSTGRES_PASSWORD: password
web:
build: .
# コンテナ起動時にserver.pidを削除し、rails sを実行する
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
# ホストのカレントディレクトリをコンテナの/myappと同期させる
volumes:
- .:/myapp
# ホストとコンテナ間をポートフォワードする
ports:
- '3000:3000'
# サービス間の依存関係
depends_on:
- db
# Docker環境でByebugを使用
stdin_open: true
tty: true
###Gemfile
Gemfileに関してはデフォルトで入っているもの主となる。
追加したパッケージはコメントしているため不要であれば削除して構わない
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.6'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
#デバックツールの導入
gem 'pry-rails'
gem 'pry-byebug'
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '~> 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
#自動補完用ツールの導入
gem 'solargraph'
#静的コード解析ツールの導入
gem 'rubocop'
gem 'rubocop-rails'
#erbのフォーマットツールの導入
gem 'htmlbeautifier'
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of web drivers to run system tests with browsers
gem 'webdrivers'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
###package.json
package.jsonについてはvue-routerとvuexを使いたいため追加している
Vuetify等、UIフレームワークを使用したいようであれば追加する。
{
"name": "myapp",
"private": true,
"dependencies": {
"@rails/actioncable": "^6.0.0",
"@rails/activestorage": "^6.0.0",
"@rails/ujs": "^6.0.0",
"@rails/webpacker": "4.3.0",
"turbolinks": "^5.2.0",
"vue": "^2.6.12",
"vue-loader": "^15.9.3",
"vue-template-compiler": "^2.6.12",
"vue-router": "^3.0.1",
"vuex": "^3.0.1"
},
"version": "0.1.0",
"devDependencies": {
"webpack-dev-server": "^3.11.0"
}
}
##Railsでデバッグする
VScode上のターミナルを開く
以下をターミナルで実行
docker-compose exec web rails console
pry が起動
[1] pry(main)>
postコントローラーを作成
docker-compose exec web rails g controller post index
post_controller.rbを修正
class PostController < ApplicationController
def index
@post = Post.all
end
end
postのモデルを作成
docker-compose exec web rails g model post name:string age:integer
DBにモデルを反映させる
docker-compose exec web rails db:migrate
index.html.erbを以下に書き換え
<%= @post.name %>
<%= @post.age %>
routes.rbを以下に修正
Rails.application.routes.draw do
root to: 'post#index'
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
pryでPostモデルのインスタンスを作成
@post = Post.new
=> #<Post:0x00005589bc4beb78 id: nil, name: nil, age: nil, created_at: nil, updated_at: nil>
#まだnameやageにはデータを入れていない
#DBに保存もされていない
Post.all
=> Post Load (2.2ms) SELECT "posts".* FROM "posts"
[]
#DBにインスタンスを保存する
@post.save
(0.7ms) BEGIN
Post Create (5.9ms) INSERT INTO "posts" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id" [["created_at", "2020-09-23 13:06:47.962085"], ["updated_at", "2020-09-23 13:06:47.962085"]]
(3.1ms) COMMIT
=> true
#もう一度Post.allをしてデータをDBから取得すると保存したインスタンスが呼び出される
Post.all
=> Post Load (2.2ms) SELECT "posts".* FROM "posts"
[#<Post:0x00005589bceec5f0
id: 1,
name: nil,
age: nil,
created_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00,
updated_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00>]
#@postインスタンスにデータを入れてみる
@post.name = "Hiro"
=> "Hiro"
@post.age = "29"
=> "29"
#再び保存
@post.save
Post Update (4.0ms) UPDATE "posts" SET "name" = $1, "updated_at" = $2 WHERE "posts"."id" = $3 [["name", "Hiro"], ["updated_at", "2020-09-23 13:10:26.486888"], ["id", 1]]
Post Update (2.0ms) UPDATE "posts" SET "age" = $1, "updated_at" = $2 WHERE "posts"."id" = $3 [["age", 29], ["updated_at", "2020-09-23 13:10:56.785029"], ["id", 1]]
(1.0ms) COMMIT
=> true
#データが保存されている
Post.all
=> Post Load (1.4ms) SELECT "posts".* FROM "posts"
[#<Post:0x00007f1ddc7a77a8
id: 1,
name: "Hiro",
age: 29,
created_at: Wed, 23 Sep 2020 13:06:47 UTC +00:00,
updated_at: Wed, 23 Sep 2020 13:10:56 UTC +00:00>]
Webブラウザで以下にアクセス
http://localhost:3000
以下のようにDBからデータを取得できればOK
####Binding.pryを試してみる
post_controller.rbを修正
class PostController < ApplicationController
def index
binding.pry
@post = Post.all
end
end
Webブラウザで以下にアクセス
http://localhost:3000
pryのターミナルに戻る
pry(main)>
以上で、pryでデバッグする環境が整った
##参考
以下のサイトを参考にさせていただきました。
Docker ドキュメント日本語化プロジェクト
クィックスタート: Compose と Rails
Dockerfile のベストプラクティス
Webpacker の基本的な仕組み
Dockerを使って「Rails / PostgreSQL」の開発環境を作ろう!