

### 実現したいこと

nginxのfrontendとSpring bootで作ったbackendを疎通させたい。

### 前提

VPS上にdockerをインストールし以下の構成を作成しwebアプリケーションをデプロイしています。

  * frontend：vue
  * backend：Spring boot
  * DB：Mysql

※frontendとbackendの疎通は開発環境により確認済み  
※backendとDBの疎通も確認済み

フォルダ構成は以下のようになっています。

[code]

    Workspace
    ├─docker-compose-verifi.yml
    ├─.vscode
    ├─infra
    │  ├─spring
    │  │  └─Dockerfile.verifi
    │  └─vue
    │     ├─Dockerfile.verifi
    │     └─nginx-verifi.conf
    ├─spring_workspace(backendコンテナにvindマウント)
    └─vue_workspace(frontendコンテナにvindマウント)
        └─front_app
            ├─node_modules
            ├─public
            └─src
    
[/code]

#### 環境構築フロー

  0. docker-compose -f docker-compose-verifi.ymlを実行
  1. [frontend]-node.js環境でビルド後productionステージでビルド結果を配置
  2. [backend]-builderステージでSpring bootプロジェクトをビルド後openjdk環境にビルド結果を配置

### 発生している問題・エラーメッセージ

マルチステージビルドを用いてnode.js環境でビルドしたjsファイルをnginxに配置して配信しようとしています。  
node.js環境でyarn run
serveを実施した場合は正常に動作しますが、node.js環境でビルドしたファイルをnginxのwebrootの位置に配置するとバックエンドとの通信ができなくなってしまします。  
ブラウザのコンソールには何も表示されておらず、バックエンドのSpring
bootのログにも何も表示されていないのでビルド時に正しくjsのパスがマッピングされておらず、APIRequestを実行できていないと予想しvue.config.jsにpublicPathを追加して再実行しても変化ありませんでした。

Webアプリケーションの開発の知識が疎いため原因と解決法をご教授いただけると幸いです。  
よろしくお願いいたします。

### 該当のソースコード

docker-compose-verifi.yml

[code]

    version: "3.9"
    services:
      
      backend:
        container_name: spring-container
        build: 
          context: .
          dockerfile: ./infra/spring/Dockerfile.verifi #backend構築用
          args:
            HOST_ENV: http://<ホストIPアドレス>:9001　#通信を許可するIPアドレス
            DATABASE_URL: <DBサーバーIPアドレス> #DBのIPアドレス
        ports:
          - 8080:8080
        expose:
          - 8080
        working_dir: /srv
        tty: true
        environment:
          DATABASE_URL: <DBサーバーIPアドレス>
          HOST_ENV: http://<ホストIPアドレス>:9001
        
      frontend:
        container_name: vue-container
        build: 
          context: .
          dockerfile: ./infra/vue/Dockerfile.verifi
        ports:
          - 9001:80
        working_dir: /app
        volumes:
          - node_modules:/app/node_modules
      
        environment:
          VUE_APP_BASE_URL: http://<ホストIPアドレス>:8080
          VUE_APP_BROWSER_BASE_URL: http://<ホストIPアドレス>:8080
        
    volumes:
      node_modules:
      deploy_modules:
    
[/code]

Dockerfile.verifi(backend環境構築用)

[code]

    FROM eclipse-temurin:17-jdk AS builder
    
    WORKDIR /srv/app
    ARG HOST_ENV
    ENV HOST_ENV=${HOST_ENV}
    ARG DATABASE_URL
    ENV DATABASE_URL=${DATABASE_URL}
    COPY ./spring_workspace/app /srv/app
    COPY ./spring_workspace/app/pom.xml /srv/ap
    RUN apt update
    RUN apt-get -y install maven
    RUN mvn package
    
    FROM openjdk:17-alpine
    COPY --from=builder /srv/app/target/*.jar /app/app.jar
    EXPOSE 8080
    ENTRYPOINT ["java", "-jar", "/app/app.jar"]
    
[/code]

Dockerfile.verifi(frontend環境構築用)

[code]

    FROM node:20-alpine3.17 as build-stage
    
    # ENV NODE_ENV production
    
    WORKDIR /app
    
    COPY ./vue_workspace/front_app /app
    COPY ./vue_workspace/front_app/package*.json ./
    COPY ./vue_workspace/front_app/yarn.lock ./
    RUN yarn install
    COPY ./vue_workspace/front_app/ /app/
    RUN mkdir -p /usr/share/nginx/html && \
        yarn run build
    
    
    #マルチステージビルド：build-stageでビルドした/usr/share/nginx/html以下をnginxのwebroot以下に配置する。
    FROM nginx:1.17.10-alpine as production-stage
    
    RUN mkdir /app
    COPY --from=build-stage /usr/share/nginx/html /usr/share/nginx/html
    COPY ./infra/vue/nginx-verifi.conf /etc/nginx/conf.d/default.conf
    EXPOSE 80
    CMD ["nginx", "-g", "daemon off;"]
    
[/code]

nginxの設定ファイル

[code]

    server {
      listen       80;
      server_name  <hostのIPアドレス>;
      location / {
        root   /usr/share/nginx/html;
        index  index.html;
        try_files $uri $uri/ /index.html;
      }
      error_page   500 502 503 504  /50x.html;
      location = /50x.html {
        root   /usr/share/nginx/html;
      }
    
      location ~ ^/css/*\.(css)$ {
        root /usr/share/nginx/html;
    
      }
      location ~ ^/[^/]*\.(css)$ {
        root /usr/share/nginx/html/css;
    
      }
    
      location ~ ^/js/*\.(js)$ {
        root /usr/share/nginx/html;
    
      }
      location ~ ^/[^/]*\.(js)$ {
        root /usr/share/nginx/html/js;
    
      }
    
      location ~ ^/img/*\.(jpg|jpeg|png|gif|ico|woff|woff2|ttf)$ {
        root /usr/share/nginx/html;
    
      }
      location ~ ^/[^/]*\.(jpg|jpeg|png|gif|ico|woff|woff2|ttf)$ {
        root /usr/share/nginx/html/img;
    
      }
    
      access_log  /var/log/nginx/access.log  main;
      error_log  /var/log/nginx/error.log warn;
    }
    
[/code]

### 試したこと

①ビルドパスの変更  
ボタンの挙動や画面遷移の動作、backへのAPIRequestの動作が想定通りでないことから、画面とjsが結びついていないと考えビルド先のフォルダ構成をnginxと同じ構成に設定しました。  
また、ビルド時に相対パス設定に変更しましたが状況変わらずwebコンソールにエラー表示もなく期待通りの動作になりませんでした。

vue.config.js

[code]

    const { defineConfig } = require('@vue/cli-service')
    module.exports = defineConfig({
        transpileDependencies: true,
        devServer:{
            port: 80,
            client:{
                webSocketURL: 'ws://0.0.0.0:80/ws',
            },
            allowedHosts: 'all',
        },
        outputDir: '/usr/share/nginx/html',
        publicPath: './'
    
    })
    
[/code]

②開発環境との差分確認  
開発環境ではfrontend起動のDockerfileをproductnステージがない状態のものを使用しています。

Dockerfile.dev(frontend環境構築用)

[code]

    FROM node:20-alpine3.17 as build-stage
    
    ENV NODE_ENV production
    
    WORKDIR /app
    
    COPY ./vue_workspace/front_app /app
    COPY ./vue_workspace/front_app/package*.json ./
    COPY ./vue_workspace/front_app/yarn.lock ./
    RUN yarn install
    COPY ./vue_workspace/front_app/ /app/
    
[/code]

こちらを用いてfrontendを構築後、コンテナ内にてyarn run serveを実行すると正常に動作しています。  
開発環境と検証環境の違いはfrontendの実行環境がnode.jsかnginxかの違いのみですので  
②の結果から

  1. nginxの設定ファイルに不備がある
  2. ビルド方法に不備がある

のどちらかだと考えていますが、見直してみても不具合箇所が特定できませんでした。


CC BY-SA 4.0
2023-11-22T11:33:02.060
96891
2023-11-23T02:12:57.310
2023-11-23T02:12:57.310
3060
60509
question
docker vue.js
マルチステージビルドしたvueアプリケーションコンテナがAPIコンテナと疎通できない