くま's Tech系Blog

基本的には技術で学んだことを書き留めようと思います。雑談もやるかもね!

DockerでVue.jsの環境構築を行う

今回はDockerでVue.jsの環境構築を行います。

前提として以前記事にしたRailsプロジェクトをDockerで作成する手順を確認した上で続きとして読み進めてください

kumaskun.hatenablog.com

今回は、バックエンドをRailsでフロントエンドをVue.jsで合わせて1つのプロジェクトとして作成していきます。 下記イメージです。

root
├── compose.yml
├── backend (Rails プロジェクト)
├── client (Vue.js プロジェクト)
     └── Dockerfile

また、今回はViteを使用してVue.jsプロジェクトを作成します。

Viteは今までのビルドツール(Vue CLI等)に比べて、高速で動作するビルドツールといわれています。

vitejs.dev

プロジェクト作成の準備

まずはcompose.ymlの修正を行います。 下記を追加します。

// 下記を追加
client:
    build:
      context: ./client
      dockerfile: Dockerfile
      args:
        WORKDIR: $WORKDIR
    volumes:
      - ./client:/$WORKDIR:cached
    ports:
      - "5173:5173"
    depends_on:
      - backend

volumesでは、ボリュームのマウントを行います。 ボリュームとはデータを永続化できる場所のことで、外部HDDに近いイメージです。 コンテナは破棄すると消えてしまうため、データを永続化したいときは、コンテナの外にデータを置く必要があります。 そしてマウントとは、ホスト側(コンテナの外)にあるディレクトリやファイルを、コンテナの中から利用できるようにすることです。 volumesの指定は、コロンの左にホストのパスを、右にコンテナのパスを指定します。

そして、Vue.jsのプロジェクト内でDockerfileを作成します。

FROM node:18.15.0-bullseye

ARG WORKDIR

ENV HOME=/${WORKDIR}

WORKDIR ${HOME}

// apt updateコマンドを実行してパッケージリストを更新し、yarn installコマンドを実行してNode.jsアプリケーションに必要なパッケージをインストールする
RUN apt update \
    && yarn install

CMD ["yarn", "dev", "--host"]

ここまで作成した状態で、下記コマンドを実行します。

$ docker-compose build

エラーが発生しなければ先に進みます。

次にプロジェクトの新規作成を行います。下記コマンドを実行します。

$ docker-compose run --rm client npm init vite@latest

コマンドを実行するとProject nameとSelect a frameworkとSelect a variantの設定を求められます。

今回は、「Project name」はvite-project、「Select a framework」はVue、「Select a variant」はJavaScriptとします。(適宜置き換えてプロジェクトを作成してください)

成功するとclient配下にvite-projectというフォルダが作成されていると思います。

ここからはvite-projectの中身を移動して、空になったvite-projectを削除します。 下記ターミナルで実行します。(フォルダ名は適時置き換えて実行してください)

$ ls -A client/vite-project 
.gitignore     .vscode        README.md      index.html     package.json   public         src            vite.config.js

$ mv client/vite-project/* client 

$ ls -A client/vite-project        
.gitignore .vscode

$ mv client/vite-project/.gitignore client/ && mv client/vite-project/.vscode client 

$ ls -A client/vite-project
// 空なので何も表示されなければOK!

$ rmdir client/vite-project 

これでvite-projectにあったファイルはVue.jsプロジェクトのルートに配置されたと思います。

ローカル起動できるようにする

ここからはlocalhostで起動できるようにします。

まずは、yarnを使用するためインストールを行います。 npmのままがいい方は、yarn installのところをnpm installに置き換えて実行してください。

両方とも、Javascriptのパッケージマネージャーです。 yarnはnpmと互換性があり、npmで使用していたプロジェクト設定ファイル(package.json)がそのまま使えます。

今回下記の理由でyarnを選択しています。

  • npmと比べてインストールが速い、セキュリティが高い。インストール時にパッケージが不正に変更されていないかなどをチェックサムを用いて検証することができ、安全なパッケージのインストールが可能
  • オフラインキャッシュの仕組みを利用している。パッケージを初めてインストールすると、Yarnはそのパッケージを~/.yarn-cacheの下にあるキャッシュフォルダに追加する。これによりnpmと比較してYarnのパフォーマンスを大幅に向上させている
$ docker-compose run --rm client yarn install 
yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.

yarnを使用できるようになったらDockerfileを修正します。

FROM node:18.15.0-bullseye

ARG WORKDIR

ENV HOME=/${WORKDIR}

WORKDIR ${HOME}

RUN apt update \
    && yarn install

// ここを追加
COPY . ./
COPY package.json /client/package.json
COPY yarn.lock /client/yarn.lock

CMD ["yarn", "dev", "--host"]

COPY package.json /client/package.jsonCOPY yarn.lock /client/yarn.lockを行う理由は起動の時間を短縮するためです。 dockerはビルド開始時にdocker daemonにDockerfileのディレクトリにあるファイルを全部tarして(アーカイブを作成/展開)送ります。 コンテナ内にパッケージの一覧とバージョンの依存関係が書かれたファイルだけコピーして、その後コンテナ内でインストールする方が時間を短縮できます。

そして、compose.ymlを修正します。

// volumesを追加
volumes:
  node_modules:
services:
  db:
  backend:
  client:
    build:
      context: ./client
      dockerfile: Dockerfile
      args:
        WORKDIR: $WORKDIR
    volumes:
      - ./client:/$WORKDIR:cached
      // ここを追加
      - node_modules:/$WORKDIR/node_modules
    ports:
      - "5173:5173"
    depends_on:
      - backend

ここで、追加した内容を少し補足します。

volumesでバインドマウントを設定しています。 カレントディレクトリをまるごとマウントしてしまうと node_modules もホストとコンテナで同期されてしまうことになります。(ホスト側の情報がそのまま反映される) これだとホスト側に node_modules が作成されて、意図しない挙動を招きかねません。(node_modules をいじったりしてしまうなど)

また、バインドマウントはマウント時にホスト側の情報がそのまま反映され、そのあとコンテナ内で変更があればホスト側に反映されます。 するとコンテナ内のnode_modulesがなくなるパターンもあります。 これを避けるためには以下のように名前付きボリュームを用意する(volumes:のこと)ことで node_modules が名前付きボリュームに格納され、ホストマシンに同期されることがなくなります。 そのための設定をここでは追加しています。

この状態で、docker-compose buildを行ってから、docker-compose upを実行します。

$ docker-compose build --no-cache

$ docker-compose up

docker-compose up実行後にエラーが発生していなければ、http://localhost:5173/ にアクセスしてください。 下記画面が表示されれば疎通できています。

参照

qiita.com

qiita.com

kyoruni.hatenablog.com

qiita.com

hub.docker.com

choice-site.com

jdlm.info