react+nginx+docker環境の構築
なんで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