【Docker】Vue.jsのSPA開発環境(Node+PHP+Nginx+Mysql)

今回はフロントがVue.js、バックエンドがフレームワークなしのPHP、のローカル開発環境を構築します。
Vueはvue-cliを使用してプロジェクトを作成します。

ファイル構成

spa-projectディレクトリを本番サーバに転送する想定です。
spaの起点となるindex.htmlは、project/front-web/index.htmlになります。
vueプロジェクトをビルドするとdist ディレクトリ(/vue-project/dist)以下にビルドファイルが置かれるので、/vue-project/dist ↔︎ spa-project/project/front-web が同期されるようにdockerで設定していきます。

spa-project/
├── project    //デプロイ時、サーバに置くディレクトリ
  │   ├── front-web    // vueのビルドファイルが置かれる
  │   │   (└── index.html)
  │   ├── apiとか色々
  │  └──....
│
├── spa-dev  //docker環境構築ディレクトリ
  │   ├── app    // PHPコンテナ
  │   │   ├── Dockerfile
  │   │   └── php.ini
  │   ├── db     // MySQLコンテナ
  │   │   ├── Dockerfile
  │   │   └── my.conf
  │   ├── nginx    // nginxコンテナ
  │   │  ├── Dockerfile
  │   │ └── default.conf
  │   └── node     // Nodeコンテナ
  │        └── Dockerfile
  └──  docker-compose.yml    // 全コンテナの管理
│
├── vue-project   //vueのプロジェクトを置くディレクトリ

docker-compose.yml

services:
  app:
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
    volumes:
      - ../project/:{本番環境サーバのプロジェクトを置くパス}
  node:
    build:
      context: .
      dockerfile: ./docker/node/Dockerfile
    ports:
      - 8081:8081
    depends_on:
      - app
    stdin_open: true
    tty: true
    volumes:
      - ../vue-project:/vue-project #vue-cliで作成するプロジェクト名
      - ../project/front-web/:/vue-project/dist
      - node_modules_volume:/vue-project/node_modules
  nginx:
    build:
      context: .
      dockerfile: ./docker/nginx/Dockerfile
    ports:
      - 8080:80
    depends_on:
      - app
    volumes:
      - ../project/:{本番環境サーバのプロジェクトを置くパス}
  db:
    build: 
      context: .
      dockerfile: ./docker/db/Dockerfile
    ports:
      - 3306:3306
    environment:
      MYSQL_DATABASE: ****
      MYSQL_USER: ****
      MYSQL_PASSWORD: ****
      MYSQL_ROOT_PASSWORD: ******
      TZ: "Asia/Tokyo"
    volumes:
      - mysql-volume:/var/lib/mysql
      - ./docker/db/init_dump:/docker-entrypoint-initdb.d/
volumes:
  mysql-volume:
  node_modules_volume:

ポート(ブラウザを介しての接続)

nginxで8080ポートを解放し、PHPアプリケーションに接続できるようにします。APIやビルド後のvueの確認はこちらを使っていきます。(本番環境を模した感じです)

vueの開発はnpm run serveで開発サーバを立てると思いますので、nodeで8081ポートを開けました。

vueは変更毎にいちいちビルドするのは面倒です。開発サーバだとホットリロードのような感じで変更を検知して自動的に反映してくれます。

Vue開発時は、ブラウザで8081にアクセスしてvueを表示し、vue内でAPIに接続するときは8080ポートに向かって通信しにいく感じになっています。

nodeコンテナのVolume

nodeコンテナのVueプロジェクトがローカルの/vue-projectディレクトリにマウントされます。ただし、/vue-project/distと/vue-project/node_modulesは除外されます。

/vue-project/dist
nodeコンテナの/vue-project/dist内は、Vueファイルをビルドしたファイルが置かれます。(つまり本番用ファイル) なのでnginxコンテナで表示できるようにマウント場所をproject/front-web/(SPA起点)にし、nginxで表示可能できるようにします。

/vue-project/node_modules
dockerはマウントするファイルが多いと動作がかなり重くなります。
node_modulesやcomposerのvendorなどはローカルのファイルをマウントするのではなく、dockerのコンテナ内でinstallする形にしましょう。

詳しくはこちら:https://blog.clairvoyance.co.jp/2024/07/29/%e3%80%90docker%e3%80%91laravel%e3%81%a8%e3%81%8bvue%e3%81%ae%e3%83%ac%e3%82%b9%e3%83%9d%e3%83%b3%e3%82%b9%e3%81%8c%e3%82%84%e3%81%9f%e3%82%89%e9%81%85%e3%81%84%e6%99%82%e3%81%ab/

ttyとstdin_open

Dockerのコンテナは、実行中のプロセスが終了するまで停止せず、プロセスがアクティブである限りコンテナもアクティブです。逆にプロセスが終了した場合は停止してしまいます。
nginxなどはフォアグラウンドでプロセスを実行するようになっているのでプロセスが終了しないのですが、nodeやgoのコンテナ等は持続的にプロセスを実行するものがデフォルトでないので正常終了してしまいます。
このようなコンテナはttyを設定し、標準入出力をするものを用意してあげるとコンテナが継続されます。またstdin_openでその標準入出力とエラー出力をローカル側のdocker専用の標準入出力に接続させることができます。

参考:
https://zenn.dev/hohner/articles/43a0da20181d34

各コンテナのDockerfile

今回は各コンテナで特別な処理はしてないですが、参考までに載せておきます。

PHP Dockerfile

FROM php:7.4.27-fpm

ENV TZ Asia/Tokyo

RUN apt-get update && \
  apt-get install -y git unzip libzip-dev libicu-dev libonig-dev && \
  docker-php-ext-install intl pdo_mysql mysqli mbstring zip bcmath

COPY ./app/php.ini /usr/local/etc/php.ini
COPY --from=composer /usr/bin/composer /usr/bin/composer

WORKDIR {プロジェクトルート}

Mysql Dockerfile

FROM mysql:8.0.27

COPY ./db/my.conf /etc/my.conf

Nginx Dockerfile

FROM nginx:1.20.2-alpine
WORKDIR /
ENV TZ Asia/Tokyo

COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

default.conf

server {
    listen 80;
    root {本番環境サーバのプロジェクトを置くパス};

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.html?$query_string;
    }

    location = /favicon.ico {

    access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /404.html;

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location /api {
        root {本番環境サーバのプロジェクトを置くパス}/api;
    }
}

Vueプロジェクト(ビルド後)
http://localhost:8080/front-web/~

API
http://localhost:8080/api/~

Node Dockerfile

FROM node:18-alpine
WORKDIR /vue
RUN npm install -g @vue/cli

EXPOSE 81

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール