문제 해결을 위해 아래 단계들을 순서대로 점검해 보시길 바랍니다.
1단계: 브라우저 개발자 도구로 원인 파악하기 (가장 먼저 할 일)
가장 먼저 브라우저에서 문제의 원인을 직접 확인해야 합니다.
- CSS가 깨진 화면에서 F12 키를 눌러 개발자 도구를 엽니다.
- ‘Console’ (콘솔) 탭으로 이동합니다.
Failed to load resource: the server responded with a status of 404 (Not Found)와 같은 에러가 보인다면, 브라우저가 CSS 파일을 찾지 못했다는 의미입니다. (가장 흔한 경우)Refused to apply style from '<URL>' because its MIME type ('text/html') is not a supported stylesheet MIME type...와 같은 에러가 보인다면, CSS 파일 경로로 요청했는데 Nginx가 CSS 파일 대신 HTML(아마도index.html)을 응답으로 줬다는 의미입니다.
- ‘Network’ (네트워크) 탭으로 이동합니다.
- CSS, JS 등 파일 목록을 확인합니다.
- CSS 파일의 ‘Status’가 404 (Not Found) 로 표시되는지 확인합니다.
- 만약 404가 맞다면, 해당 CSS 파일의 ‘Request URL’ 경로가 올바른지 확인해야 합니다.
이 단계를 통해 “브라우저가 어떤 경로로 CSS 파일을 요청했는데 실패했는가?”를 파악하는 것이 문제 해결의 시작입니다.
2단계: 주요 원인 및 해결 방법
개발자 도구에서 확인한 내용을 바탕으로 아래 해결책들을 적용해 보세요.
원인 1: Nginx가 정적 파일(CSS, JS 등)의 경로를 제대로 처리하지 못하는 경우 (가장 흔함)
React Router 등을 사용하면 모든 경로 요청(http://도메인/some/path)이 index.html을 보도록 설정하는 경우가 많습니다. 이 설정이 CSS, JS, 이미지 파일 같은 정적 파일 요청까지 가로채서 index.html을 반환하게 되면 MIME 타입 에러가 발생합니다.
✅ 해결 방법: Nginx 설정 파일 수정 (/etc/nginx/sites-available/your-config)
Nginx 설정에서 특정 경로(예: /static) 또는 특정 확장자(.css, .js)에 대한 요청은 index.html로 보내지 말고, 실제 파일 경로에서 찾도록 명시적인 location 블록을 추가해야 합니다.
수정 전 (문제의 소지가 있는 설정):
|
1 2 3 4 5 6 7 8 9 10 |
<code class="whitespace-pre-wrap break-words"><span class="line"><span>server {</span></span> <span class="line"><span> # ... (생략)</span></span> <span class="line"><span> </span></span> <span class="line"><span> location / {</span></span> <span class="line"><span> root /var/www/react-app/build;</span></span> <span class="line"><span> index index.html;</span></span> <span class="line"><span> try_files $uri $uri/ /index.html; # 모든 요청을 index.html로 보냄</span></span> <span class="line"><span> }</span></span> <span class="line"><span>} </span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span> |
수정 후 (권장하는 설정):
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<code class="whitespace-pre-wrap break-words"><span class="line"><span>server {</span></span> <span class="line"><span> listen 80;</span></span> <span class="line"><span> server_name your-domain.com;</span></span> <span class="line"><span></span></span> <span class="line"><span> root /var/www/react-app/build; # root를 server 블록 레벨로 올리는 것이 좋음</span></span> <span class="line"><span> index index.html;</span></span> <span class="line"><span></span></span> <span class="line"><span> # / 경로에 대한 기본 처리</span></span> <span class="line"><span> location / {</span></span> <span class="line"><span> try_files $uri $uri/ /index.html;</span></span> <span class="line"><span> }</span></span> <span class="line"><span></span></span> <span class="line"><span> # 특정 확장자에 대한 처리 (CSS, JS 등 정적 파일)</span></span> <span class="line"><span> # 이 location 블록을 추가하여 정적 파일을 우선적으로 처리하게 함</span></span> <span class="line"><span> location ~* \.(?:css|js|ico|png|jpg|jpeg|gif|svg)$ {</span></span> <span class="line"><span> expires 1y; # 캐시 설정 (선택 사항)</span></span> <span class="line"><span> add_header Cache-Control "public";</span></span> <span class="line"><span> # try_files $uri =404; # 파일이 없으면 404 반환</span></span> <span class="line"><span> }</span></span> <span class="line"><span>}</span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span> |
설정 설명:
location ~* \.(?:css|js|...)$: 정규식을 사용하여.css,.js등 특정 확장자로 끝나는 모든 요청을 이 블록에서 처리하도록 합니다.- 이 블록 안에는
try_files ... /index.html부분이 없으므로, Nginx는 해당 요청을root디렉토리에서 실제 파일로 찾아 제공합니다. - 이렇게 하면 일반적인 페이지 라우팅 요청은
location /블록이, 정적 파일 요청은location ~* \. ...블록이 각각 처리하게 되어 문제가 해결됩니다.
설정 수정 후에는 반드시 Nginx를 재시작해야 합니다.
|
1 |
<code class="whitespace-pre-wrap break-words"><span class="line"><span>sudo</span><span> systemctl</span><span> restart</span><span> nginx</span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span> |
원인 2: React 프로젝트의 homepage 설정 문제
package.json 파일의 homepage 속성은 React 앱이 어떤 경로를 기준으로 정적 파일(CSS, JS)의 경로를 생성할지 결정합니다. 이 설정이 잘못되면 CSS 파일의 경로가 꼬이게 됩니다.
- 예시:
homepage를"/my-app"으로 설정하면, CSS 파일 경로는<link href="/my-app/static/css/main.css">와 같이 생성됩니다. 하지만 Nginx는/static/css/main.css에서 파일을 찾으려고 하므로 404 에러가 발생합니다.
✅ 해결 방법:
- 루트 경로에서 서비스하는 경우 (http://도메인.com/):
package.json파일에서homepage속성을 제거하거나,"."또는""로 설정합니다.1234567<code class="whitespace-pre-wrap break-words"><span class="line"><span>// package.json</span></span><span class="line"><span>{</span></span><span class="line"><span> "name"</span><span>: </span><span>"my-app"</span><span>,</span></span><span class="line"><span> "version"</span><span>: </span><span>"0.1.0"</span><span>,</span></span><span class="line"><span> // "homepage": "/my-app", <-- 이 줄을 삭제하거나 주석 처리</span></span><span class="line"><span> ...</span></span><span class="line"><span>}</span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span>
- 하위 경로에서 서비스하는 경우 (http://도메인.com/my-app/):
package.json에서homepage를 해당 경로로 정확히 설정합니다.12<code class="whitespace-pre-wrap break-words"><span class="line"><span>// package.json</span></span><span class="line"><span>"homepage"</span><span>: </span><span>"/my-app"</span></span></code>
- 그리고 Nginx 설정에서도 해당 하위 경로를 처리하도록
location블록을 수정해야 합니다.
설정 수정 후에는 반드시 React 프로젝트를 다시 빌드하고, 빌드된 파일을 서버에 다시 배포해야 합니다.
|
1 |
<code class="whitespace-pre-wrap break-words"><span class="line"><span>npm</span><span> run</span><span> build</span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span> |
원인 3: 파일 권한 문제
Nginx 프로세스(보통 www-data 사용자)가 배포된 React 빌드 파일(build 폴더 및 그 안의 파일들)을 읽을 수 있는 권한이 없는 경우, 파일을 찾지 못해 404 에러를 반환할 수 있습니다.
✅ 해결 방법: build 폴더의 소유권과 권한을 Nginx 사용자에게 부여합니다.
|
1 2 3 4 |
<code class="whitespace-pre-wrap break-words"><span class="line"><span># /var/www/react-app/build 경로에 배포했다고 가정</span></span> <span class="line"><span>sudo</span><span> chown</span><span> -R</span><span> www-data:www-data</span><span> /var/www/react-app/build</span></span> <span class="line"><span>sudo</span><span> chmod</span><span> -R</span><span> 755</span><span> /var/www/react-app/build </span></span></code></code><code class="whitespace-pre-wrap break-words"><span class="line"><span></span></span> |
문제 해결 체크리스트
- [브라우저] 개발자 도구(F12) Console/Network 탭에서 CSS 파일 요청이 404 에러인지, MIME 타입 에러인지 확인한다.
- [Nginx] 설정 파일에 정적 파일(
css,js등)을 위한 별도의location블록이 있는지 확인하고 없다면 추가한다. (sudo systemctl restart nginx필수) - [React]
package.json의homepage설정이 현재 서비스 경로와 맞는지 확인한다. (수정했다면npm run build후 재배포 필수) - [서버] 배포된
build폴더의 파일 권한이 Nginx 사용자(e.g.,www-data)에게 올바르게 부여되었는지 확인한다.
대부분의 경우 2번(Nginx 설정) 또는 **3번(React homepage 설정)**에서 문제가 해결됩니다. 이 두 가지를 가장 먼저 점검해 보시는 것을 추천합니다.