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
Nakano
Nakano
Back-end engineer

AWS,Rails,UE4,vue.js,hugo,その他なんでもやりたい

関連項目