web_bonsaiの日記

web開発の学習日記です。誰に見せるためでもないただの日記です。

Next.jsのサービスを追加してブラウザでNext.jsのスタートページを表示する | Mac + Docker + Rails + Next.js その0033

参考にさせていただいたページ

createする

TSでやっていくので、docker-compose.ymlのあるディレクトリで以下のコマンドを実行しました。

% yarn create next-app --ts frontend

frontend/Dockerfileの作成とその記述内容

% vim frontend/Dockerfile

以下の通り記述しました。

FROM node:16.16

ENV APP_PATH /usr/src/app
RUN mkdir $APP_PATH
WORKDIR $APP_PATH

COPY package.json yarn.lock $APP_PATH/
RUN yarn

COPY . $APP_PATH/

docker-compose.ymlの編集とその記述内容

% vim docker-compose.yml

以下の通りfrontendサービスを追加しました。:3000はrailsに割り当てられているので、frontendは:3001を使うことにします。

version: "3.9"
services:
  〜略〜
  frontend:
    build:
      context: ./frontend
    ports:
      - '3001:3001'
    command: 'yarn dev'
    volumes:
      - ./frontend:/usr/src/app

この段階で、ローカル環境のdocker-compose.ymlの記述内容は以下の通りです。

version: "3.9"
services:
  nginx:
    build: ./nginx
    ports:
      - "8000:8000"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/html:/var/www/html
      - ./nginx/log:/var/log
    depends_on:
      - app
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - 80:80
      - 443:443
    restart: always
    environment:
      DOMAINS: 'localhost -> http://nginx:8000'
      STAGE: local
    volumes:
      - ./https_portal/ssl_certs:/var/lib/https-portal
    depends_on:
      - nginx
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  app:
    build: ./rails
    ports:
      - "3000:3000"
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./rails:/myapp
    environment:
      - RAILS_SERVE_STATIC_FILES=false
      - RAILS_ENV=development
    depends_on:
      - db
  frontend:
    build:
      context: ./frontend
    ports:
      - '3001:3001'
    command: 'yarn dev'
    volumes:
      - ./frontend:/usr/src/app

frontend/package.jsonの編集とその記述内容

package.jsonのscripts.devを以下の通り編集します。

  "scripts": {
    "dev": "next dev -p 3001",
    〜略〜
  },

ここまでやった段階でのfrontend/package.jsonの記述内容は以下の通りです。

{
  "name": "frontend",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev -p 3001",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "next": "12.2.1",
    "react": "18.2.0",
    "react-dom": "18.2.0"
  },
  "devDependencies": {
    "@types/node": "18.0.3",
    "@types/react": "18.0.15",
    "@types/react-dom": "18.0.6",
    "eslint": "8.19.0",
    "eslint-config-next": "12.2.1",
    "typescript": "4.7.4"
  }
}

buildする

一度buildしてみます。

% docker-compose build

upする

upします。

% docker-compose up

ブラウザでhttpの3000と3001を確認してみる

以下のURLにブラウザでアクセスすると、それぞれページが表示されます。

downする

一度downします。

% docker-compose down

nginx/nginx.confの編集とその記述内容

以下の行を追記します。

  # upstreamのnextjsを定義
  upstream nextjs {
    # server service名:3001; のように記述
    server frontend:3001;
  }

serverのブロックのlocationを変更します。railsのcontrollerをnamespace/mpa//api/でそれぞれ作成しているので、nginxのlocationも合わせています。

  server {
  〜略〜
    # location
    location /index.html {
      index index.html;
    }

    # location
    location /mpa/ {
      #proxy_set_header X-CSRF-Token $http_x_csrf_token;
      #proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://puma/mpa/;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      #proxy_set_header X-Forwarded-Proto $scheme;
      proxy_redirect off;
    }

    # location
    location /api/ {
      #proxy_set_header X-CSRF-Token $http_x_csrf_token;
      #proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://puma/api/;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      #proxy_set_header X-Forwarded-Proto $scheme;
      proxy_redirect off;
    }

    # location
    location / {
      proxy_pass http://nextjs/;
      proxy_set_header Host $http_host;
      proxy_redirect off;
    }
  }

ここまでやった段階でのnginx/nginx.confは以下の通りになっています。

user nginx;

events {
  # 1ワーカーの接続数
  # worker_connections 2048;

  # 複数のリクエストを同時に受け付けるか
  multi_accept on;

  # 複数アクセスをさばくためにI/O多重化に使うシステムコールを指定する
  use epoll;
}

http {
  # HTTPレスポンスヘッダのContent_Typeに付与する文字コード
  charset UTF-8;

  # HTTPレスポンスヘッダのServerにnginxのバージョンを入れるか(開発時以外は入れないほうが吉)
  server_tokens off;

  # MIMEタイプと拡張子の関連付けを定義したファイルを読み込む
  include /etc/nginx/mime.types;

  # 上記したmime.typesにマッチしなかった場合の設定
  # octet-streamは任意のバイナリコードを意味し、ブラウザでは実行したりせず、単にダウンロードする挙動をとるらしい
  default_type application/octet-stream;

  # upstreamのpumaを定義
  upstream puma {
    # server service名:3000; のように記述
    server app:3000;
  }

  # upstreamのnextjsを定義
  upstream nextjs {
    # server service名:3001; のように記述
    server frontend:3001;
  }

  # web-bonsai.techの設定 (nginx:8000 の設定)
  server {
    # リスニングポート
    listen 8000;

    # ドメイン設定(ローカル環境ではlocalhostで、本番環境ではドメインを設定する。)
    # server_name web-bonsai.tech;
    server_name localhost

    # HTTPレスポンスヘッダのContent_Typeに付与する文字コード
    charset utf-8;

    # logの出力先
    access_log /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    # ドキュメントルート
    root /var/www/html;

    # location
    location /index.html {
      index index.html;
    }

    # location
    location /mpa/ {
      #proxy_set_header X-CSRF-Token $http_x_csrf_token;
      #proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://puma/mpa/;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      #proxy_set_header X-Forwarded-Proto $scheme;
      proxy_redirect off;
    }

    # location
    location /api/ {
      #proxy_set_header X-CSRF-Token $http_x_csrf_token;
      #proxy_set_header X-Real-IP $remote_addr;
      proxy_pass http://puma/api/;
      #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      #proxy_set_header X-Forwarded-Proto $scheme;
      proxy_redirect off;
    }

    # location
    location / {
      proxy_pass http://nextjs/;
      proxy_set_header Host $http_host;
      proxy_redirect off;
    }
  }
}

再度buildする

再度buildしてみます。

% docker-compose build

upする

再度upします。

% docker-compose up

ブラウザでhttpsを確認してみる

以下のURLにブラウザでアクセスすると、それぞれページが表示されます。

https://localhost/ 」にアクセスしてコンソールを見ると以下のようなエラーが出ていますが、Hot Module Replacementに関するエラーなので一旦そのままにしておくことにします。

WebSocket connection to 'wss://localhost/_next/webpack-hmr'

failed:

init    @   websocket.js?a9be:45
connectHMR  @   websocket.js?a9be:30
eval    @   next-dev.js?3515:40

ちなみに「 http://localhost:3001/ 」にアクセスした場合はこのエラーは発生しません。

今回はここまでにしておきます。