Laravel을 Docker 기반의 Sail로 운영하고, Nginx를 호스트 서버(Ubuntu)에 리버스 프록시로 구성해 SSL을 적용했는데도, 브라우저에서 Mixed Content: HTTP 리소스를 요청했기 때문에 차단됨이라는 경고를 받았습니다.
빌드 결과에는 HTTPS가 잘 적용되어 있었는데, 도대체 왜 이런 문제가 발생했을까요?
💡 문제 상황 요약
- Laravel Sail은 Docker 컨테이너 내부에서 실행
- 호스트 서버는 Nginx를 설치해 SSL(HTTPS) 적용 및 리버스 프록시 설정
- vite.config.js에 base: 'https://도메인/build/' 명시하고, NODE_ENV=production으로 빌드도 완료
- public/build/manifest.json에도 http://는 없음
- 그럼에도 브라우저 HTML 출력에서는 모든 정적 자산 경로가 http://도메인/...으로 표시됨
- Laravel의 @vite() 혹은 Vite::prefetch()가 HTTP 링크를 출력하고 있었음
❗ 원인: Laravel이 HTTPS 요청을 HTTP로 인식하고 있었음
리버스 프록시 구조에서 Laravel은 실제로는 HTTPS 요청인데도 자체적으로는 HTTP 요청으로 인식합니다.
그래서 asset()이나 @vite() 같은 URL 생성기에서 http:// 경로를 만들고 있었던 것이죠.
이는 Laravel이 request()->isSecure() 를 기준으로 URL을 결정하기 때문입니다.
리버스 프록시를 사용할 경우, 이 값이 잘못 판단될 수 있습니다.
✅ 해결 방법: HTTPS 강제 인식 설정
Laravel의 AppServiceProvider에서 명시적으로 HTTPS를 강제 설정하면 문제는 즉시 해결됩니다.
app/Providers/AppServiceProvider.php
이 설정으로 Laravel은 request()->isSecure() 를 true로 인식하고,
모든 URL 생성기는 기본적으로 https://로 생성됩니다.
🔄 대안: Nginx에서 헤더 전달
Nginx 설정에서 아래 헤더를 Laravel로 넘기면 Laravel이 HTTPS 요청임을 더 정확히 판단할 수 있습니다.
그러나 이 경우 Laravel의 TrustProxies 미들웨어를 잘 설정해야 하며, Docker 환경에 따라 의도대로 동작하지 않는 경우가 있어
코드에서 직접 HTTPS를 강제하는 방식(URL::forceScheme)을 추천합니다.
🔒 Mixed Content 없이 안전한 서비스 제공!
이 설정 이후, 더 이상 "Mixed Content" 경고 없이 모든 정적 자산(JS, CSS, 이미지 등)이 https://로 잘 로드되었고,
Google Chrome의 보안 자물쇠도 다시 활성화되었습니다. 🎉
✅ 요약 정리
문제 | Laravel이 HTTPS 요청을 HTTP로 인식해 혼합 콘텐츠 오류 발생 |
환경 | Laravel Sail + Nginx 리버스 프록시 + Let's Encrypt |
핵심 해결 | URL::forceScheme('https') 로 HTTPS 강제 |
부가 설정 | proxy_set_header X-Forwarded-Proto https; |
Laravel 버전 | 9 이상, Vite 플러그인 사용 중 |
Laravel을 Docker로 운영 중이라면, 정적 자산 HTTPS 문제는 대부분 이 구조로 인해 발생하니 꼭 위 설정을 확인해보시기 바랍니다.
'IT & 개발 > laravel' 카테고리의 다른 글
Laravel 외래 키 삭제 처리 – onDelete() 옵션 정리 (1) | 2025.05.07 |
---|---|
Laravel에서 Custom Role Middleware 만들기 (0) | 2025.02.10 |
Laravel에서 increment() 메서드 사용 시 즉시 업데이트되지 않는 문제 해결하기 (0) | 2024.12.02 |
Laravel에서 데이터 정렬하기: orderBy 메소드 활용하기 (2) | 2024.11.25 |
라라벨에서 커스텀 helper 등록하기 (3) | 2024.10.07 |