はじめに
Gaiax Group Advent Calendar 2018の初日の記事です。
今進めているプロダクト開発でNuxt.jsを使う機会があり、環境構築をより理解するために今回Qiitaに書こうと思いました。
前提として、Ruby on Railsの環境がそこにあるとして進めていきます。
技術スタック
今回の環境構築での技術スタックは以下のようになります。
- ruby 2.5.3
- Rails 5.1.6
- node 8.1.2
- MySQL 5.7
Railsのプロジェクトを作成
では環境構築を行なっていきます。
以下のコマンドでnuxt-rails-app
という名前でアプリケーションを作成します。
$ rails _5.1.6_ new nuxt-rails-app --api -d mysql
--api
と書いて上げることでAPIモードになります。
Dockerfileを作成
次にルートディレクトリ直下にDockerfileを作成します。
作成できたらDockerfileに以下のコードを追加してください。
nuxt-rails-app (ルートディレクトリ)
└── Dockerfile
FROM ruby:2.5.3-slim
RUN apt-get update -qq \
&& apt-get install -y build-essential default-libmysqlclient-dev \
&& rm -rf /var/lib/apt/lists/* \
&& gem update
WORKDIR /app
COPY Gemfile /app/
# COPY Gemfile.lock /app/
RUN bundle install -j4
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
Gemfile.lock
のところをコメントアウトしている理由は、自分のPCの環境にMySQLが入っておらず、rails new
した際にGemfile.lock
ファイルが作成されていないためです。rails new
した際にGemfile.lock
が作成される場合はGemfile.lock
のところのコメントアウトはしなくて大丈夫です。
docker-compose.ymlを作成
次にルートディレクトリ直下にdocker-compose.ymlを作成します。
作成できたらdocker-compose.ymlに以下のコードを追加してください。
nuxt-rails-app (ルートディレクトリ)
└── docker-compose.yml
version: '2'
services:
db:
image: mysql:5.7.23
restart: always
environment:
MYSQL_ROOT_PASSWORD: nuxt-rails-app
volumes:
- ./db/mysql/volumes:/var/lib/mysql
web:
build: .
ports:
- 3000:3000
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/app
links:
- db
env_file:
- .env
tty: true
stdin_open: true
.envと.env.exampleを作成
次に.envファイルと.env.exampleファイルをルートディレクトリ直下に作成します。
作成したら、.env.exampleに以下のコードを追加します。
USER=root
PASSWORD=
HOST=db
.gitignoreを編集
次に.envファイルとdb/mysqlがコミットされないように.gitignoreファイルに以下のコードを追加します。
.env
db/mysql
Railsのデフォルト画面を表示
以下のコマンドでビルドを実行します。
$ docker-compose build
次にコンテナを作成して、起動します。
$ docker-compose up -d
上記のコマンドを実行したらlocalhost:3000にアクセスして、Railsのデフォルト画面が表示されていればうまく動作しています。
Dockerfileのコメントアウトを外す
DockerfileのGemfile.lockのところのコメントアウトを外します。
FROM ruby:2.5.3-slim
RUN apt-get update -qq \
&& apt-get install -y build-essential default-libmysqlclient-dev \
&& rm -rf /var/lib/apt/lists/* \
&& gem update
WORKDIR /app
COPY Gemfile /app/
# この行のコメントアウトを外す
COPY Gemfile.lock /app/
RUN bundle install -j4
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
docker-compose.ymlにfrontendコンテナの記述を追加する
次にdocker-compose.ymlにfrontendコンテナの記述を追加します。
version: '2'
services:
db:
image: mysql:5.7.23
restart: always
environment:
MYSQL_ROOT_PASSWORD: nuxt-rails-app
volumes:
- ./db/mysql/volumes:/var/lib/mysql
web:
build: .
ports:
- 3000:3000
command: bundle exec rails s -p 3000 -b '0.0.0.0'
volumes:
- .:/app
links:
- db
env_file:
- .env
tty: true
stdin_open: true
# ここから追加
frontend:
build: ./frontend
tty: true
ports:
- 8000:3000
command: yarn dev
volumes:
- .:/app
Nuxtのプロジェクトを作成
まず以下のコマンドでvue-cliとvue/cli-initをインストールします。
$ npm install -g @vue/cli
$ yarn global add @vue/cli-init
次に以下のコマンドでNuxtのプロジェクトを作成します。
$ vue init nuxt-community/typescript-template frontend
次にfrontendディレクトリに移動してyarn install
を実行します。
$ cd fronend
$ yarn install
frontendディレクトリの中にDockerfileを作成
次にfrontendディレクトリ内にDockerfileを作成します。
frontend
└── Dockerfile
FROM node:8.12-slim
WORKDIR /app/frontend
ENV PATH /app/frontend/node_modules/.bin:$PATH
RUN apt-get update -qq \
&& rm -rf /var/lib/apt/lists/*
ENV TZ Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY package.json /app/frontend/package.json
COPY yarn.lock /app/frontend/yarn.lock
RUN yarn install --no-progress --registry http://registry.npmjs.org/
ENV HOST 0.0.0.0
Nuxtの画面を表示
まず、以下のコマンドを実行して、コンテナを停止させます。
$ docker-compose down
次に以下のコマンドでコンテナを起動させます。
$ docker-compose up -d
上記のコマンドを実行したら、http://localhost:8000にアクセスして以下の画面が表示されればうまく動作しています。
これで環境構築は終了ですが、Elementも導入してみます。
Element UIも使ってみよう
Vue.js上で高機能なUIコンポーネントが使えるライブラリ「Element」は非常に便利なので、Elementの導入もここに記載したいと思います。
参考) Element
まず、element-ui
をインストールします。
$ yarn add element-ui
次にnuxt.config.js
に以下のコードを追加します。
frontend
└── nuxt.config.js
.
.
.
// この行にelement-ui/lib/theme-chalk/index.cssを追加する
css: ["~/assets/css/main.css", "element-ui/lib/theme-chalk/index.css"],
build: {},
modules: [
"@nuxtjs/axios",
"~/modules/typescript.js"
],
// この行を追加する
plugins: ["~plugins/element-ui"],
axios: {}
}
次にfrontendディレクトリにpluginsディレクトリを作成し、作成したpluginsディレクトリにelement-ui.jsというファイルを作成します。作成したらelement-ui.jsに以下のコードを追加します。
frontend
└── plugins
└── element-ui.js
import Vue from "vue"
import ElementUI from "element-ui"
import locale from "element-ui/lib/locale/lang/ja"
Vue.use(ElementUI, { locale })
これでElementを実装できる準備が整いました。
では、Elementが使えるか試していきたいと思います。
frontend/pages
ディレクトリにform.vueを作成し、form.vueに以下のコードを追加します。
frontend
└── pages
└── form.vue
<template>
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="Activity name">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="form.region" placeholder="please select your zone">
<el-option label="Zone one" value="shanghai"></el-option>
<el-option label="Zone two" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Activity time">
<el-col :span="11">
<el-date-picker
type="date"
placeholder="Pick a date"
v-model="form.date1"
style="width: 100%;"
></el-date-picker>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="11">
<el-time-picker
type="fixed-time"
placeholder="Pick a time"
v-model="form.date2"
style="width: 100%;"
></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="Instant delivery">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="Activity type">
<el-checkbox-group v-model="form.type">
<el-checkbox label="Online activities" name="type"></el-checkbox>
<el-checkbox label="Promotion activities" name="type"></el-checkbox>
<el-checkbox label="Offline activities" name="type"></el-checkbox>
<el-checkbox label="Simple brand exposure" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="Resources">
<el-radio-group v-model="form.resource">
<el-radio label="Sponsor"></el-radio>
<el-radio label="Venue"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="Activity form">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Create</el-button>
<el-button>Cancel</el-button>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
return {
form: {
name: "",
region: "",
date1: "",
date2: "",
delivery: false,
type: [],
resource: "",
desc: ""
}
};
},
methods: {
onSubmit() {
console.log("submit!");
}
}
};
</script>
上記のコードはElementの公式ドキュメントのこちらをコピーしただけです。
コードを追加できたら、以下のコマンドを実行してコンテナの再起動を行います。
$ docker-compose down
$ docker-compose up -d
上記のコマンドを実行したら、http://localhost:8000/formにアクセスします。すると下記のようにフォームのUIが表示されます。
このようにElementを使えば簡単にUIを作ることができるので非常に便利です。
以上でRails・Nuxt.js の環境をDockerでつくりElementの導入まで行いました。
読んでくださってありがとうございました。