はじめに
いなたつアドカレの二十四日目の記事です。
Dockerを使ってReactで作ったアプリケーションをnginx上にポイ投げするためのあれですね。
DockerってなにとかnginxってなにReactってなにってのはスルーで行きます。
今回の記事はcreate-react-app(以下CRA)を使用する前提となっています。
つかうもの
- react
- react-router
- nginx
- docker
完成系
react-router使ってnginx上でリンクに#がつかないかつリロードしても404にならない構成の作成
ディレクトリ構成
- app
- docker
- react
- Dockerfile
- nginx
- default.conf
- react
- web
- docker-compose.yml
- docker
こんなかんじです
dockerディレクトリにdockerで使用するファイルを格納しています。
webディレクトリにCRAで作成したアプリが入りますね。
DockerでReact
version: '3'
services:
react_app:
container_name: react_app
build: ./docker/react
command: npm start
volumes:
- ./web:/app
ports:
- 3000:3000
つづいて
docker/react/Dockerfile
FROM node
WORKDIR /app
ここは基本的になんでも構いません(めんどくさかった)
作成するアプリケーションに合わせてpackage.jsonなどを用意してあげてください。
今回は めんどくさいので これでいきます。
Dockerで んぎっくす
はい、Nginxいきます
nginx:
image: nginx
container_name: nginx
ports:
- 8080:80
volumes:
- ./web/build:/var/www
- ./docker/nginx/:/etc/nginx/conf.d/
depends_on:
- react_app
web(CRAのディレクトリ)の中のbuildをnginxコンテナにマウントしています。
docker/nginx
には設定ファイルですね。
server {
listen 80;
location / {
root /var/www;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
buildをマウントしてそのマウントしたファイルのindex.htmlを表示するぜ〜って感じですね。
Reactのコンポーネント構成
import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Hello from './Pages/Hello'
import Changed from './Pages/Changed'
function App() {
return (
<Router>
<Route exact path='/' component={Hello} />
<Route exact path='/changed' component={Changed} />
</Router>
);
}
export default App;
react-router
で2つのページを遷移できるようにします。
import React from 'react';
import {Link} from 'react-router-dom'
const Hello = () => {
return (
<div>
<div>Hello</div>
<Link to='/changed'>ぺーじせんい</Link>
</div>
)
}
export default Hello;
import React from 'react';
const Changed = () => {
return (
<div>
<div>Changed</div>
</div>
)
}
export default Changed;
ページ遷移するだけですね。
うごかしてみる
とりあえずreactのプロジェクトをbuildしましょう。
localhost:8080
にアクセスします。
こんな感じですね。
ページ遷移してみます。
遷移できましたね。おっけーです。
ちょっとリロードしたくなってきたわ
あっあっあっ
だめですね。んぎっくす
さんに怒られちゃいました。
ハッシュルーターとかダサいじゃん?
URLに「#」とかつくHashルーターをつかうことでこれを解決することはできます。
localhost:8080/#/changed
だっっっっっっっっっさあああああい
やだよ。
解決しよう
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;
}
}
try_files $uri /index.html;
この一行を書くだけですね。
ほら、リロードしてみてくださいよ、怒られますか?怒られませんよね。
これで解決ですね。
なぜ解決できたのか
とりま解決でけたらえーねんって人はみなくてよきですえ
nginxにはtry_files ディレクティブというものが存在し、これは、引数を前から順番にファイルが存在するかをtryしまくって行ってくれます。そして見つからなかった場合はindex.html
を返却しましょうねっていう感じです。
何も見つからなかったら404を返すよ〜って実装をする場合もありますね。