Docker
Next.js 이미지 최적화가 외부 도메인에서만 실패한 원인
로컬에서는 잘 보이던 이미지를 배포 후 next/image로 바꾸면서 깨뜨린 과정을 정리했다.
증상: 썸네일만 배포 서버에서 깨졌다
블로그 카드에 외부 CDN 이미지를 붙였는데 로컬 개발 서버에서는 정상이고 배포 서버에서만 썸네일이 회색 영역으로 남았다. 처음에는 CDN 캐시나 mixed content 문제라고 생각했지만, 브라우저 콘솔에는 Next.js 이미지 최적화 경로인 /_next/image 요청이 400으로 찍혀 있었다.
헷갈렸던 지점은 <img>로 바꾸면 바로 보인다는 점이었다. 그래서 네트워크보다는 next/image가 허용하는 원격 이미지 조건을 먼저 봐야 했다.
확인한 순서
먼저 실제 이미지 주소가 서버에서 접근 가능한지 확인했다.
curl -I "https://cdn.example.com/uploads/thumb.png"
그다음 배포된 앱에서 최적화 엔드포인트가 어떤 URL을 받는지 봤다. 개발자 도구의 Network 탭에서 실패한 요청을 열어 보니 url= 파라미터의 호스트가 images.example-cdn.com이었다. 내가 설정에 넣은 도메인은 cdn.example.com이라서 서로 달랐다.
수정한 설정
단순히 domains 배열에 하나를 추가할 수도 있지만, 서브도메인과 경로 조건을 명확히 두고 싶어서 remotePatterns로 바꿨다.
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.example-cdn.com',
pathname: '/uploads/**',
},
],
},
};
배포 환경에서는 설정 파일 변경 뒤 앱을 다시 빌드해야 한다. 컨테이너만 재시작하고 빌드를 안 해서 한 번 더 삽질했다.
npm run build
pm run start
내가 세운 기준
외부 이미지가 안 보이면 CSS보다 아래 순서로 본다.
- 원본 이미지 URL이 직접 열리는가
/_next/image요청의 상태 코드가 무엇인가next.config.js의 hostname이 실제 요청 hostname과 같은가- 설정 변경 뒤 새 빌드가 반영됐는가
- 운영 환경 변수로 이미지 base URL을 바꾸고 있지 않은가
마무리
이번 문제는 이미지 컴포넌트 자체보다 운영 주소와 설정 주소가 달라진 것이 핵심이었다. 앞으로 외부 이미지를 붙일 때는 화면에서 보이는 URL이 아니라 Network 탭의 실제 요청 URL을 기준으로 설정을 맞추기로 했다.