외부 이미지를 next/image에 넣었더니 hostname is not configured로 죽은 이유
문제 발생
외부 CDN 이미지를 그대로 넣었더니 런타임에서 실패했습니다.
<Image src="https://cdn.example.com/a.png" width={400} height={300} alt="" />Error: Invalid src prop (https://cdn.example.com/a.png) on `next/image`,
hostname "cdn.example.com" is not configured under images in your `next.config.js`unoptimized를 붙이면 사라지길래 그렇게 넘어갈까 고민했습니다.
원인 분석
허용 목록이 없으면 우리 서버가 남의 이미지 최적화 서버가 됩니다. Next.js 문서가 목적을 그대로 적습니다 — next.config.js에서 remotePatterns를 사용해 특정 외부 경로의 이미지만 허용하고 나머지는 차단합니다. 이는 우리 계정의 외부 이미지만 서빙되도록 보장합니다.
이 제한이 없다면 아무나 /_next/image?url=<임의 URL>을 호출해 우리 인프라의 대역폭과 CPU로 이미지를 변환시킬 수 있습니다. 오류 메시지는 사고가 아니라 설계된 거부입니다.
unoptimized로 끄는 것은 오류만 없애는 방법입니다. 그 순간 리사이징·포맷 변환·캐싱이 전부 사라져, next/image를 쓰는 이유 대부분이 함께 사라집니다.
해결 방안
- 필요한 호스트만 등록합니다. 경로까지 좁힐수록 좋습니다.
// next.config.ts
export default {
images: {
remotePatterns: [
{ protocol: "https", hostname: "cdn.example.com", pathname: "/account123/**" },
],
},
};- URL 형태로도 쓸 수 있습니다. 문서가 제시하는 간결한 형태입니다.
images: { remotePatterns: [new URL("https://cdn.example.com/account123/**")] }-
와일드카드를 남발하지 않습니다.
hostname: "**.example.com"은 서브도메인을 열어주는 것이고, 문서에 따르면 이때도 쿼리 문자열과 커스텀 포트는 여전히 차단됩니다.hostname: "**"처럼 전부 여는 설정은 위에서 말한 프록시 문제를 그대로 되살립니다. -
쿼리 문자열이 필요하면
search를 명시합니다. 버전 파라미터가 붙는 CDN에서는 이 설정이 없으면 계속 거부됩니다. -
사용자가 URL을 입력하는 기능이라면 설계를 다시 봅니다. 임의 외부 이미지를 표시해야 한다면 허용 목록으로는 감당이 안 됩니다 — 업로드받아 우리 스토리지에 저장하는 쪽이 SSRF·가용성 측면에서 안전합니다.
-
로컬에서만 확인하고 끝내지 않습니다. 이 설정은 서버 재시작이 필요하고, 배포 환경의 CDN 호스트가 로컬과 다른 경우가 많습니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.