[TIL 87일 차] Sprint Mission12
오늘의 성취
1. 개발 진행 상황
- 배포 아키텍처 구성하기
- Nginx 기반 리버스 프록시 컨테이너 구성
- 애플리케이션 서버, DB, Redis, Kafka가 외부 네트워크와 단절되도록 설정
2. 문제

브라우저에서 http://localhost:3000 접속 시 index.html은 내려오지만 화면이 흰색으로 표시됨
Chrome 개발자 도구의 Console에서는 아래와 같은 오류가 발생
Failed to load module script:
Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/plain".
Strict MIME type checking is enforced for module scripts per HTML spec.
이 오류는 브라우저가 JavaScript 파일을 받기 했지만, 그 파일을 JavaScript로 인정하지 않았다는 뜻이다.
현재 index.html은 JavaScript 파일을 아래처럼 불러온다.
<script type="module" crossorigin src="/assets/index-bOSCxVDt.js"></script>
여기서 type="module"로 불러오는 JavaScript 파일은 MIME 타입 검사가 엄격하게 적용된다. 따라서 서버는 JavaScript 파일을 내려줄 때 아래와 같은 응답 헤더를 보내야 한다.
Content-Type: application/javascript
하지만 문제가 발생했을 때 Nginx는 아래처럼 JavaScript 파일을 내려왔다.
Content-Type: text/plain
브라우저 입장에서는 “이 파일은 JavaScript가 아니라 일반 텍스트 파일인데, module script로 실행하려고 한다”고 판단한다. 그래서 보안 정책에 따라 JavaScript 실행을 차단한다. 이로 인해 index.html은 정상적으로 로드되어 탭 제목이 Discodeit으로 보였지만, 앱을 렌더링하는 JavaScript가 실행되지 않아 화면이 비어있던 것이다.
이 문제가 발생한 직접적인 원인은 nginx.conf를 직접 작성해 /etc/nginx/nginx.conf에 마운트하면서, Nginx 기본 설정에 MIME 타입 매핑 설정이 빠졌기 때문이다.
Nginx는 정적 파일을 내려줄 떄 확장자에 따라 적절한 Content-Type을 붙여야 한다. 예를 들어 .html은 text/html, .css는 text/css, .js는 application/javascript로 내려줘야 한다. 그런데 MIME 타입 매핑이 빠져 있으면 Nginx가 .js 파일을 JavaScript로 인식하지 못하고 기본 타입으로 내려줄 수 있다.
그래서 nginx.conf의 http {...} 블록 안에 아래 설정을 추가해야 한다.
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# ...
}
include /etc/nginx/mime.types;- Nginx에 확장자별 MIME 타입 목록을 불러오게 한다.
.js파일은application/javascript,.css파일은text/css,./html은text/html로 응답한다.
default_type application/octet-stream;- MIME 타입 목록에 없는 파일을 만났을 때 사용할 기본 타입을 지정
application/octet-stream- 정확한 형식은 알 수 없는 일반 바이너리 파일이라는 의미
- 알 수 없는 파일을 임의로 텍스트나 HTML처럼 해석하지 않게 만드는 안전한 기본값
프로젝트 요구 사항
3. 기본 요구사항
//...
3-03. 배포 아키텍처 구성하기

- 다음의 다이어그램에 부합하는 배포 아키텍처를 Docker Compose를 통해 구현하세요.
Reverse Proxy- Nginx 기반의 리버스 프록시 컨테이너를 구성하세요.
- 역할 및 설정은 다음과 같습니다:
/api/*,/ws/*요청은 Backend 컨테이너로 프록시 처리합니다.- 이 외의 모든 요청은 정적 리소스(프론트엔드 빌드 결과)를 서빙합니다.
- 프론트엔드 정적 리소스는 Nginx 컨테이너 내부의 적절한 경로(
/usr/share/nginx/html등)에 복사하세요.
- 프론트엔드 정적 리소스는 Nginx 컨테이너 내부의 적절한 경로(
- 외부에서 접근 가능한 유일한 컨테이너이며,
3000번 포트를 통해 접근할 수 있어야 합니다.
Backend- Spring Boot 기반의 백엔드 서버를 Docker 컨테이너로 구성하세요.
Reverse Proxy를 통해/api/*,/ws/*요청이 이 서버로 전달됩니다.
DB,Memory DB,Message BrokerBackend컨테이너가 접근 가능한 다음의 인프라 컨테이너들을 구성하세요- DB: PostgreSQL
- Memory DB: Redis
- Message Broker: Kafka
- 각 컨테이너는 Docker Compose 네트워크를 통해 백엔드에서 통신할 수 있어야 합니다.
- 외부 네트워크와 단절되어야 합니다.
//...
GitHub Repository 주소
https://github.com/JungH200000/10-sprint-mission/tree/sprint12
Leave a comment