Vue Rails Docker環境でCreateとRead
はじめに
dockerでフロントはvuecliでapiサーバーはrailsapiで作成しています。
軽めにCreateとReadするとこまで。
構成
今回はこういうディレクトリ構成で環境を作ろうかと思います。
.
├── docker-compose.
├── vue
│   └ Dockerfile
└── web
    └─Dockerfile
webディレクトリ以下はrailsの環境を配置します。
作成
[ターミナル]
mkdir [プロジェクト名] && cd $_
mkdir vue
ディレクトリを作ったのでdockerfileとcomposeを書いていきます。
[docker-compose.yml]
version: '3.2'
services:
  vue:
    build: vue
    #command: bash -c "yarn install && yarn serve"
    ports:
      - 1234:8080
    volumes:
      - type: bind
        source: ./vue
        target: /app/vue
    stdin_open: true
    tty: true
解説
build: vue
vue/Dockerfileをビルドします。
ports: - 1234:8080
コンテナ内のlocalhost8080をローカル環境の1234につなげる
volumes:
ローカルのvueディレクトリ以下をコンテナ内の/app/vueと同期
tty: trueとstdin_open: trueについて
- docker run の「-it」オプションに当たるもの。これを指定しないと、コンテナを起動してもすぐ終了してしまうので注意
 
[vue/Dockerfile]
FROM node:14.4.0-stretch-slim
WORKDIR /app/vue
RUN apt-get update && \
yarn global add @vue/cli
CMD ["/bin/bash"]
ここまで書いたら一回ビルドしてvue createします。
docker-compose up -d
docker-compose exec vue bash
/app/vue# vue create .
Vue CLI v4.4.4
? Generate project in current directory? (Y/n) y
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features 
ここでvue-routerを選びます、あとはデフォルトです。
exit
docker-compose down
vue createでできた.gitを削除
rm -rf vue/.git
railsapiの作成
mkdir web && cd $_
rails new . --api -d postgresql
rm -rf .git
cd ..
[web/Dockerfile]
FROM ruby:2.7.1-slim-buster
ENV RUBYOPT='-W:no-deprecated -W:no-experimental'
RUN apt-get update -qq && \
    apt-get install -y build-essential \
                       patch ruby-dev \
                       zlib1g-dev liblzma-dev \
                       libpq-dev postgresql-client
WORKDIR /app/web
ADD . /app/web
RUN bundle
RUN mkdir -p tmp/sockets
composeを修正します。
[docker-compose.yml]
version: '3.2'
services:
  db:
    image: postgres:13-alpine
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: rails_user
      POSTGRES_PASSWORD: password
    volumes:
      - ./tmp/db:/var/lib/postgresql/data:cached
  web:
    build: web
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - type: bind
        source: ./web
        target: /app/web
        consistency: cached
    environment:
      RAILS_ENV: development
      DATABASE_HOST: db
      DATABASE_PORT: 5432
      DATABASE_USER: rails_user
      DATABASE_PASSWORD: password
    ports:
      - 3000:3000
  vue:
    build: vue
    command: bash -c "yarn install && yarn serve"
    ports:
      - 1234:8080
      - 8000:8000
    volumes:
      - type: bind
        source: ./vue
        target: /app/vue
        consistency: cached
      - type: bind
        source: ./.yarn-cache
        target: /usr/local/share/.cache/yarn/v6
        consistency: cached
    stdin_open: true
    tty: true
database.ymlを書き換える
[web/config/database.yml]
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("DATABASE_USER") { rails_user } %>
  password: <%= ENV.fetch("DATABASE_PASSWORD") { password }%>
  pool: 5
  host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
  port: 5432
起動
docker-compose up
DB作成
別ターミナルを作成して、DBとAPIを作成します。
docker-compose run web rails db:create
docker-compose run web rails g scaffold book name --api
docker-compose run web rails db:migrate
[rails c]
Book.create(name: "book1")
Book.create(name: "book2")
デフォルトのデータ作成は完了です。
api連携するために、vueとrailsそれぞれに設定を追加します。
CORSで弾かれないために以下の追記をします。apiが増えてくると別の設定を増やさないといけないですね。
[vue/vue.config.js]
module.exports = {
  devServer: {
    proxy: 'http://web:3000'
  }
};
block hostで弾かれないように以下の追記をします。
[web/config/environments/development.rb]
Rails.application.configure do
  config.hosts << "web"
.
.
end
readとcreateの作成
railsからgetやpostするためにaxiosというライブラリをしようします。
docker-compose run vue yarn add axios
[vue/src/views/About.vue]
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <form v-on:submit.prevent="create">
      <label>name</label>
      <input type="text" v-model="name">
      <button>create</button>
    </form>
    <ul>
      <li v-for="book in books">{{ book.name }}</li>
    </ul>
  </div>
</template>
<script>
 import axios from 'axios'
 export default{
   data: function () {
     return {
       books: [],
       name: null
     }
   },
   created: function(){
     axios
       .get(`/books.json`)
       .then(response => (this.books = response.data))
       .catch(error => console.log(error))
   },
   methods:{
     create: function(){
       axios
	 .post(`books.json`,{
	   book:{
	     name: this.name,
	   }
	 })
	 .then(response => {
	   this.books.push(response.data);
	   this.name = null;
	 })
	 .catch(error => console.log(error))
     },
   }
 }
</script>
おまけ
| 用途 | command | 
|---|---|
| 起動 | docker-compose up | 
| 停止 | docker-compose down | 
| DB作成 | docker-compose run web rails db:create | 
| DB更新 | docker-compose run web rails db:migrate | 
| コンテナ再起動 | docker-compose restart | 
| railsコンテナ内のbashに | docker-compose exec web bash | 
| vueコンテナ内のbashに | docker-compose exec vue bash | 
| サーバー停止 | docker-compose run web rm tmp/pids/server.pid | 
| サーバー起動 | docker-compose run web rails s | 
| 全コンテナ停止 | docker stop $(docker ps -q) | 
| 全コンテナ削除 | docker rm $(docker ps -q -a) | 
| 全イメージ削除 | docker rmi $(docker images -q) | 
| 全ボリューム削除 | docker volume rm $(docker volume ls -qf dangling=true) | 
| 滅びの呪文 | docker-compose down –rmi all –volumes |