3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

node_modulesをPCにインストールせずにVue + Vuetifyの開発環境をDockerで作る

Posted at

何をしたいか

複数メンバーでVuetifyを使って軽く開発をすることになったのだが、各メンバーのスキルにバラツキがあるため(殆どプログラミング経験ないメンバー有)、出来るだけ事前準備無しで環境を作ろうと思ったのがきっかけである。

全員VScodeを使うが、ソースコードを置く場所がWindowsだったりMacだったり、リモートのCentOSマシンだったりとバラバラ。

それぞれの環境でnpm installしてnode_modulesのフォルダが出来て、となると結構面倒なので、git cloneしてdocker-composeすれば全て用意されるようにしたかった

今回の記事では以下の事を実現する

  • コンテナ上でnpm installをしてnpm run buildも行うが、ソースコードはホスト上に置いておきたい
  • node_modulesはコンテナ、ソースコードはホスト上、出来上がったdistもホスト上としたい
  • Dockerfileにコマンドを書くのではなく、package.jsonからまとめてインストールしたい
  • いちいちnpm run buildを実行したくないのでvue-cli-service build --watchとして自動ビルドしたい
  • FlaskのAPIサーバを使うのでNGINXのリバースプロキシも必要なため、distをNGINXに見せる

Git

#フォルダ構成

.
|-- app
|   |-- Dockerfile
|   `-- src
|-- docker-compose.yml
|-- nginx_web
|   |-- Dockerfile
|   `-- nginx_conf
`-- vuetify
    |-- Dockerfile
    |-- README.md
    |-- babel.config.js
    |-- dist
    |-- node_modules
    |-- package-lock.json
    |-- package.json
    |-- public
    |-- src
    `-- vue.config.js

Docker Compose

NGINX,Flask,Vuetifyビルド用ということで3つコンテナが立つことになる

docker-compose.yml
version: '3'
services:
  nginx_web:
    build:
      context: ./nginx_web
      dockerfile: Dockerfile
    container_name: nginx_web
    ports:
    - 80:80
    volumes:
    - ./vuetify:/usr/share/nginx/html

  vuetify:
    build:
      context: ./vuetify
      dockerfile: Dockerfile
    container_name: vuetify
    ports:
      - 1234:8080
    volumes:
      - ./vuetify:/app
      - /app/node_modules
    stdin_open: true
    tty: true

  app:
    build:
      context: ./app
      dockerfile: Dockerfile
    container_name: app
    ports:
      - 3031:3031
    volumes:
    - ./app/src:/src

nginx_webとapp(flask)コンテナの設定についてはこちらの記事を参照
jwilder nginx-proxy + letsencrypt-nginx-proxy-companion + Flask + uwsgiでHTTPS対応のWebサービスを作り、更にQualysでA+を取る
nginx_webの設定はVuetifyのbuildに対応するため少し変更してあるので、後ほど説明する

vuetifyの部分のポイントはvolumes/app/node_modules
コンテナ上にnode_modulesを展開するため、コンテナ上の/app/node_modulesはvolumeとして別途確保している。

Dockerfile

使うモジュールが増えた時にnpm install <module>を書き足すのが嫌なので、package.jsonからnpm installで片づけたい。

FROM node:alpine

WORKDIR /app

COPY ./package*.json ./

RUN apk update
RUN npm install -g npm
RUN npm install

CMD ["./node_modules/.bin/vue-cli-service", "build", "--watch"]

package.jsonには今回利用するvue,vuetify,axiosが記載されている。
PC上で一回npm installして自動で作成されたpackage.jsonをコピーして利用している

CMDにある--watchは変更ファイルを見張って自動でビルドしてくれる便利機能
ここで書かずにpackage.jsonを以下のように書いて、CMD ["npm","run","build"]としても良い

package.json
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --watch",
    "lint": "vue-cli-service lint"
  },

NGINX設定

index.htmlが./vuetify/distに出力されるのでNGINXのデフォルトのフォワード先をここにする必要がある
それが以下の記述

nginx.tpl
  server{
    listen 80;
    server_name nginx;
    location / {
      root   /usr/share/nginx/html/dist;
      index  index.html index.htm;
    }

docker-compose.ymlで

    volumes:
    - ./vuetify:/usr/share/nginx/html

としているので、http://localhostでアクセスが来たら./vuetify/dist/index.htmlが読み込まれる

Build

docker-compose up --build -dとすればOK
一回目はvuetifyのビルドに数十秒かかるのでコンテナが上がってもしばらく待とう。さもなくば404が表示される
うまくいけば以下のように表示される
image.png

#Flaskとの連携
Read Data from Flaskという部分がVuetifyのデフォルトページに追加した部分である
ソースコードはこんな感じ

server.py
from flask import Flask, jsonify, request, make_response,send_from_directory
import requests
import json

app = Flask('test')
@app.route('/api/v1/get/',methods=['GET'])
def get():
    return "Read Data from Flask",200

ただ文字を返しているだけのシンプルなAPIとしている

VueからのAPI呼び出し

Vueから先ほどの/api/v1/getを呼び出しているのがこの部分
vuetifyデフォルトのHelloWorld.vueに以下の部分を追加している

HelloWorld.vue
<template>
...省略
      <v-col cols="12" class="mb-4">
        <h1 class="display-2 font-weight-bold mb-3">
          {{flask_message}}
        </h1>
      </v-col>
...省略
<script>
import axios from "axios"

  export default {
    name: 'HelloWorld',

    created: function() {
      axios.get('/api/v1/get')
      .then(response => {
        this.flask_message = response.data
        })
    },
    data: () => ({
      flask_message: '',
...省略

結果

npmをインストールしていないWindows/Mac,Ubuntuなどで問題なく作動した。
vueファイルを変更してもビルドは非常に速い(1秒以下)
これで快適に開発が出来るようになった。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?