React 프로젝트를 Docker와 Nginx로 배포하는 과정에서 404 오류와 외부 API 호출 문제를 겪어 남기게 된 글이다.
1. 문제
1-1. 새로고침 404문제
첫쨰는 새로고침했을 때 나타나는 404 문제다.
React-Route을 통해서 서브 페이지를 만들어놓고, 사용자가 접속한 후 새로고침을 하면
페이지가 404로 날아가버리는 문제가 있었다.
이는 톰캣과 같은 WAS에 정적 빌드파일을 올렸을 때 나타난 문제와 동일한데,
404로 연결될 때 리다이렉트 주소를 React 주소와 맞춰주면 해결되는 요소다.
하지만 본 프로젝트에선 WAS를 쓰지 않고 있음에도 나타난 문제다.
1-2. 외부 API를 못 읽는 문제
문제를 인지한 건 프로젝트에 Chart.js와 같은 외부 라이브러리를 읽어온 뒤, 사용하는 과정에서 일어났다.
사진을 보면 단순히 <line>이 가입되지 않은 상태에서 사용하는데 문제가 발생 한 건데,
로컬 환경에서 npm start를 통해 실행하는 경우에는 정상적으로 화면이 보이고, 가시화되고 있다.
하지만 서버의 Docker 위에 올리는 순간, 외부에서 접속했을 때 저렇게 보인다는 것이다.
2. 해결
2-1. 문제 파악
문제를 정리해 보면, <정적 빌드 파일>을 실행하기 때문에 나타나는 문제로 보인다.
외부 API을 읽어오지 못하는 것도 정적 빌드파일에서 나타나는 문제 중 하나다.
Frontend React를 서빙하는 과정에서 정상적으로 로직이 동작하지 않는 것이다.
관련된 내용은 차차 새로운 글에서 더 자세히 작성해 보도록 하겠다.
[1-1] 404 문제
위에서 말헀던 1-1. 404 문제의 경우 Nginx 설정의 SPA(Single Page Application) 문제일 가능성이 크다. WAS가 없는데도 이러한 문제가 발생하는 건, React 프로젝트 내에서 루트 URL을 지정했을 경우 발생하는 경우가 많다.
404로 리다이렉트 될 때 루트 URL로 리다이렉트 되도록 설정하면, 자동으로 Route 경로를 인식하여 새로고침이 진행될 것으로 보인다.
하지만 우리는 지금 Nginx와 같은 프록시나 WAS를 사용하지 않을 것이기에, 해당 방법은 솔루션이 되지 못한다.
[1-2] API 문제
그럼 1-2 API를 제대로 읽어오지 못하는 문제를 보자.
당연히 이러한 문제는 서버 간 통신 또는 CORS문제로 발생할 수 있지만, 콘솔 로그를 보면 CORS문제가 아닌,
Line Element에 대한 오류 사항만 표시가 되고 있다.
이런 경우 플러그인을 사용할 때 register가 제대로 되지 않았을 경우일 수 있기 때문에, 코드를 뜯어봤다.
ChartJS.register(verticalLinePlugin, CategoryScale, LinearScale, PointElement, LineElement, BarElement, Title, Tooltip, Legend, Filler, zoomPlugin);
이것저것 다른 게 많이 있지만, LineElement도 제대로 등록되어있음을 확인했다.
그럼에도 저런 문제가 나온다는 건, 실시간 동적 데이터를 처리하는 과정에서 정적 빌드 환경은 이를 따라갈 수 없어서 나오는 문제가 있을 수 있다.
정적 파일의 경우 동적으로 움직이는 것이 아닌, 사전에 정의되어 있는 환경을 가시화해 주는 것에 특화되어 있다.
하지만 본 프로젝트의 페이지는 실시간으로 데이터가 불규칙하게 바뀌는 상태이기 때문에, Chart.js의 동적 업데이트를 정적 파일에서 불러오지 못하는 것이다.
이 가설을 기반으로 문제 해결을 위해 정적 렌더링 상태를 동적 렌더링 상태로 전환해 보도록 하겠다.
2-2. 문제 해결
2-2-1. 현황 확인
우선 지금 구축되어 있는 CICD 파이프라인을 생각해 보면,
서버에서 Nginx를 통해 Docker로 프록시 되고, Docker 내부에서도 Nginx가 실행되어 React 정적 파일로 연결되어 있었다.
React를 정적으로 사용하고 있었던 것인데, 외부 API와 각종 REST를 사용하는 대시보드(REACT 앱) 특성상
동적 렌더링을 통해 배포하여야 하는 상황이다
2-2-2. Dockerfile 수정
우선, 이 사태를 해결하기 위해 정적 렌더링 상태를 동적 렌더링으로 바꾸어야 할 필요가 있었기 때문에,
Frontend의 Dockerfile을 nginx에서 node 이미지로 변경하고, npm start 형식으로 이미지를 구축해 보았다.
현재 로컬에서 실행하고 있는 node의 버전을 확인하고, Dockerfile에 연결해 줬다.
PS D:\@Develop\smartpole\Front> node --version
v20.16.0
2-2-3. Build 및 Prod 배포 테스트
그다음, 도커 이미지를 빌드한 후 실행시켜 보았다.
PS D:\Docker-test\Front> docker logs hopeful_williams
> smartpole@0.1.0 start
> react-scripts start
(node:31) [DEP_WEBPACK_DEV_SERVER_ON_AFTER_SETUP_MIDDLEWARE] DeprecationWarning: 'onAfterSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
(Use `node --trace-deprecation ...` to show where the warning was created)
(node:31) [DEP_WEBPACK_DEV_SERVER_ON_BEFORE_SETUP_MIDDLEWARE] DeprecationWarning: 'onBeforeSetupMiddleware' option is deprecated. Please use the 'setupMiddlewares' option.
Starting the development server...
Compiled successfully!
You can now view smartpole in the browser.
Local: http://localhost:3000/xxx
On Your Network: http://xxx.xxx.xxx.xxx:3000/xxx
Note that the development build is not optimized.
To create a production build, use npm run build.
webpack compiled successfully
Compiling...
Compiled successfully!
webpack compiled successfully
실행이 되었으니, 이제 접속을 해 보면
정상적으로 페이지가 가시화되고, 새로고침도 정상적으로 동작하는 것을 알 수 있었다.
물론, 새로고침을 했을 때도 정상적으로 페이지가 가시화됨을 알 수 있었다.
3. 결론
이번 프로젝트에서 발생했던 404 오류와 외부 API 호출 문제는 정적 빌드 환경과 동적 데이터 처리 간의 불일치에서 비롯된 문제였고, React 프로젝트를 정적으로 빌드하여 Nginx를 통해 서빙하고 있었다, 이 방식으로는 실시간으로 업데이트되는 데이터를 동적으로 처리하기 어렵다는 것을 이제 알게 되었다.
이를 해결하기 위해 Docker 환경을 Nginx에서 Node.js로 전환하여 동적 렌더링 방식으로 React 애플리케이션을 배포하였고, 새로고침 시 발생하는 404 오류와 Chart.js의 데이터 불러오기 문제를 해결할 수 있었다.
또한, Docker image의 경량화와 Jenkins의 코드 최적화를 이루어낼 수 있었다.
.
정적 및 동적 렌더링의 차이를 조금이나마 더 알게 되었고, 앞으로는 프로젝트 특성에 맞는 배포 방식을 선택하는 것이 중요함을 다시금 깨달았다.
실시간 데이터를 다루는 대시보드나 앱의 경우에는 동적 렌더링 방식이 필요하다는 점, 확실히 기억하게 되었다.
더 나은 DevOps를 구현할 수 있게 될 때까지 힘내보자.
'❗ 문제 해결 > Web' 카테고리의 다른 글
[👾Troubleshooting] Jenkins + Docker 빌드 시 환경 변수 누락 이슈 (0) | 2024.09.19 |
---|