react+nginx+docker環境の構築

docker React


なんでnginxを使うの?

dockerのreact環境はnodeイメージを使用して作成します。
nodeにはサーバー機能が付属しており、npm startでサーバーが立ち上がります。
ですがnode.jsサーバーはシングルスレッドなので、nginxでリバースプロキシをしてマルチスレッドでアクセスを受け取り、node.jsサーバーに処理を投げる事で複数アクセスをさばける仕様にします。

nodeサーバーはシングルスレッドなので、reactでコンパイルした静的ファイルをnginxに配置する事でマルチスレッド処理が可能です。
(reactでコンパイルしてしまえば、jsの静的ファイルになりサーバー処理は無いので、リバースプロキシでさらに渡す必要はないみたいですね。)

また開発環境と本番環境を揃える為、dockerを使用します。

reactのDocker環境を構築

Dockerfileは下記の通り

FROM node:14.5.0-alpine

WORKDIR /usr/src/app

とりあえずnodeイメージを使用しますのでこれだけでOKです。docker-composeファイルは下記の通りを作成します。

version: '3'
services:
  react_app:
    build: ./containers/react
    volumes:
      - ./backend/:/usr/src/app
    command: sh -c "cd react-app && npm start"
    ports:
      - "3000:3000"

volumesでローカルとマウント

commandでreact-sampleフォルダに移動して
npm startでサーバーを起動してます。

この段階で下記のコマンドを実行します。

docker-compose up -d --build

次に下記のコマンドでreactをインストールします。
今回はreact-sampleという名前でreactをインストールします。

docker-compose run --rm react_app sh -c "npm install -g create-react-app && create-react-app react-app"
docker-compose up -d --build

localhost:3000にアクセスして下記の画面が表示されれば成功です。

reactとnginxとの連携

下記のコマンドでreact_appコンテナーに入る。

docker-compose exec react_app ash

reactのアプリを下記のコマンドでビルドする。

cd reat-app
npm run build

そうすると、build配下に最適化されたwebアプリファイルが出力されます。このファイルをnginxの実行環境に配置すればOKです。

一回コンテナに入ってからbuild実行してるので、入らなくてbuildできるようにしたい・・・

下記のコードで一発でbuildできます。shellコマンドとかにしておくと便利です。

docker-compose exec react_app ash -c "cd react-app/ && npm run build"

nginxのDocker環境を構築

まず、上記でdockerを立ち上げたままなら

docker-compose down

で一回dockerを落としましょう。

目標としては、reactのビルドファイル配下をnginxのpublicの実行環境にできれば完了です。
docker-composeファイルを下記のように追記します。先ほどのようにreact-appのbuildを公開したいのでvolumesに下記のように記述します。

depends_on:react_appを指定する事でnginxが後に立ち上がります。

  nginx:
    image: nginx
    container_name: nginx
    ports:
      - 10080:80
    volumes:
      - ./backend/react-app/build:/var/www
      - ./containers/nginx/:/etc/nginx/conf.d/
    depends_on:
      - react_app

また、default.confを、containers/nginx配下に設置します。
記述は下記のようにします。

server {
    listen       80;

    location / {
        root   /var/www;
        index  index.html index.htm;
        try_files $uri /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

上記の設定が終わった後に再度下記コマンドで立ち上げます。

docker-compose up -d

localhost:10080にアクセスして、reactでbuildしたファイルが表示されれば設定完了です。 (localhost:3000も普通にアクセスできます。)

お疲れ様でした!

おまけ

結局完成したdocker-compose.ymlファイルは下記になります。

version: '3'
services:
  react_app:
    build: ./containers/react
    volumes:
      - ./backend/:/usr/src/app
    command: sh -c "cd react-app && npm start"
    ports:
      - "3000:3000"
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - 10080:80
    volumes:
      - ./backend/react-app/build:/var/www
      - ./containers/nginx/:/etc/nginx/conf.d/
    depends_on:
      - react_app