web_bonsaiの日記

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

本番環境にNext.jsアプリケーションをデプロイする | Mac + Docker + Rails + Next.js その0035

今日の環境

package.jsonの編集

scripts.startを以下の通り編集します。

"start": "next start -p 3001",

ログインして移動

いつも通りsshでサーバーにログインします。

docker-compose.ymlのあるディレクトリに移動します。

git pullする

最新のコードを取得します。

docker-compose downする

不慣れな作業の前にdocker-compose downします。

$ docker-compose down

本番環境のdocker-compose.ymlのnginxサービスのdepends_onにfrontendを追記する

以下のような感じになります。

  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
      - frontend

本番環境のdocker-compose.ymlにfrontendサービスを追加する

以下の通り追記しました。本番環境なのでyarn startです。

  frontend:
    build:
      context: ./frontend
    ports:
      - '3001:3001'
    command: 'yarn start'
    volumes:
      - ./frontend:/usr/src/app

docker-compose buildする

$ docker-compose build

yarnコマンドが使えるか確認する

$ docker-compose run --rm frontend yarn -v

yarn installする

$ docker-compose run --rm frontend yarn install

yarn buildする

Next.jsアプリケーションをビルドします。

$ docker-compose run --rm frontend yarn build

docker-compose upする

$ docker-compose up

frontendサービスが以下のような感じで起動できたらOKだと思います。

frontend_1      | yarn run v1.22.19
frontend_1      | $ next start -p 3001
frontend_1      | ready - started server on 0.0.0.0:3001, url: http://localhost:3001
frontend_1      | info  - SWC minify release candidate enabled. https://nextjs.link/swcmin

一旦止める

control + c を押して一旦止めます。

docker-compose downもしておきます。

$ docker-compose down

nginx.conf にupstream nextjsを追記する

以下のような感じで追記します。

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

locationを追記する

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

    # location
    location / {
      proxy_pass http://nextjs/;
    }

docker-compose upする

以下のコマンドを実行します。

$ docker-compose up

アクセスしてみる

本番環境のURLにアクセスして、Next.jsのスタートページが表示されることを確認しました。

他のURLもこれまで通り表示されるか確認しておきます。

一旦止める

control + c を押して一旦止めます。

docker-compose downもしておきます。

$ docker-compose down

docker-compose up -dする

以下のコマンドで起動しなおします。

$ docker-compose up -d

もう一度ブラウザで確認する

もう一度ブラウザで確認します。

ここまでやった段階での本番環境の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
      - frontend
  https-portal:
    image: steveltn/https-portal:1
    ports:
      - 80:80
      - 443:443
    restart: always
    environment:
      DOMAINS: 'web-bonsai.tech -> http://nginx:8000'
      STAGE: production
    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: xxxxxxxxxx(何か強いパスワード)
  app:
    build: ./rails
    command: bash -c 'rm -f tmp/pids/server.pid && bundle exec pumactl start'
    volumes:
      - ./rails:/myapp
    environment:
      - RAILS_SERVE_STATIC_FILES=false
      - RAILS_ENV=production
      - MYAPP_DATABASE_PASSWORD=xxxxxxxxxx(何か強いパスワード)
    depends_on:
      - db
  frontend:
    build:
      context: ./frontend
    ports:
      - '3001:3001'
    command: 'yarn start'
    volumes:
      - ./frontend:/usr/src/app

ここまでやった段階での本番環境の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;
  }

  # example.comの設定 (nginx:8000 の設定)
  server {
    # リスニングポート
    listen 8000;

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

    # 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共通の設定
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-CSRF-Token $http_x_csrf_token;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;

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

    # location
    location /mpa/ {
      proxy_pass http://puma/mpa/;
    }

    # location
    location /api/ {
      proxy_pass http://puma/api/;
    }

    # location
    location / {
      proxy_pass http://nextjs/;
    }
  }
}