이번에 할 내용은 [Docker] 서버에서 react 같이 배포하기 에서 nginx를 이용해서 같이 배포하는 법을 해보았는데, 생각보다 좋은생각이 아닌것 같아서 이번에는 nodejs 서버안에 react 프로젝트를 넣어서 배포를 해볼 생각이다.
.
└── server
├── Dockerfile // 필요한 모듈 설치 및 프로젝트 빌드용 파일
├── node_modules
├── package-lock.json
├── package.json
├── .dockerignore // 도커 이미지에 넣지 않을 파일 목록
├── src
└── react // react 프로젝트
├── node_modules
├── package-lock.json
├── package.json
└── ...
위에서 보이듯이 react 프로젝트를 서버 프로젝트안에 넣어서 구동을 해볼 예정이다.
react 프로젝트는 다 만들어졌다고 가정하고, 작업해야할 파일은 Dockerfile과 서버프로젝트의 js파일만 하면된다.
// Dockerfile
FROM node:16 as builder
WORKDIR /usr/src/app/react
COPY ./react/package*.json ./
RUN npm install
COPY ./react .
RUN npm run build
FROM node:16
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY --from=builder /usr/src/app/react/build /usr/src/app/react/build
COPY . .
EXPOSE 4500
CMD ["npm", "start"]
먼저 react 프로젝트 파일들을 먼저 옮겨서 빌드를 한 뒤, 서버 프로젝트를 가져와서 빌드된 파일은 서버 프로젝트 안에 옮겨주면 된다.
const express = require('express')
const path = require('path')
const app = express()
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/react/build/index.html'))
})
이렇게 작성하면 / 경로로 이동 시 빌드된 react 프로젝트의 index.html을 전달받아 화면을 띄울수 있게 된다.
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '/react/build/index.html'))
})
서버에서 라우팅을 담당해줄 수 있지만, 리액트에서 라우팅을 사용하게 될 경우 만약 / 경로 아래로 URL을 추가로 입력해서 접속할 경우 리액트의 라우팅을 접속 요청한게 아닌, 서버의 라우팅을 요청한 것이기 때문에 아무것도 뜨지 않게 된다.
자신이 react 뷰를 띄울 URL을 하나 정하고 *을 추가해주면 그 아래 URL 경로는 전부 index.html을 받기 때문에 리액트 라우팅이 가능하게 된다.