1편에서는 Kubernetes에서 Next.js를 배포할 때 무중단 배포가 어떤 것인가에 대해서 다루었습니다. https://x2bee.tistory.com/462
2편에서는 무중단 배포 중 정적인 파일을 CDN에 올려서 하는 방법에 대해서 다루었습니다. https://x2bee.tistory.com/459
3편에서는 2편에서 적용한 무중단 배포 후 public 폴더의 처리에 대해서 다루겠습니다.
문제점
무중단 배포를 위해 static files를 아래처럼 CDN url로 바라보게 하기 위해 next.config.js
에 코드를 넣었다.
assetPrefix: (() => {
switch (process.env.APP_ENV) {
case 'stage':
return 'https://cdn.example.co.kr/stg_files/x2bee-fo-cdn'
case 'production':
return 'https://cdn.example.co.kr/files/x2bee-fo-cdn'
default:
return ''
}
})()
(참고로 위에 NODE_ENV를 APP_ENV로 customizing한 코드는 생략)
아무튼 정적인 파일(.css, .js파일들)은 잘 동작하지만, .css
에서는 문제가 생겼다.
퍼블리셔가 icon들의 이미지 파일을 '/public'에 넣어놓고, '/src'폴더에 있는 .css 파일에 이를 참조하기 위해 아래와 같은 경로로 코딩을 해놓았다.
예를들어 아래 src/assets/styles/common/icon.css
파일의 일부
.icon-arrow-right-12 {
background-image: url('/images/icons/common/ico_chevron_right_all_12.svg');
}
일반적인 경우 위 코드를 build하면 /public
폴더를 바라보게되어 브라우저에서 http://example.co.kr/images
를 바라보지만,
위에서 설정해 준 assetPrefix
는 빌드 프로세스에 globally 적용되어 위 .css
파일을 import 해 올 때 Next.js에 내재된 CSS loader를 통해 /
로 시작하는 URL을 CDN주소로 prefix로 붙어 rewrite 된다.
즉, 다시 말하면 배포 후에, https://example.co.kr/images
를 바라보아야하지만 https://cdn.example.co.kr/images
을 바라본다는 것이다.
게다가 또 하나의 문제는 여러가지 이유로 인해 CDN의 root에 images
folder를 우리팀이 쓸 수 없다. files
라는 폴더에 넣어야한다.
일단은 그 폴더에 이미지들이 있으니 우선 public 폴더의 이미지들을 CDN에 올려놓는다.
그리고 이제 해결방법은 3가지 정도가 있을 수 있다.
1번 방법: CSS 파일에 적용 url('/images'
로 시작되는 경로는 위에 next.config.js
에 설정된 assetPrefix
를 거치지 않게 하는 것이다. 그래서 cdn.example.com이 아닌 그냥 example.com (즉 localhost)를 바라보게 하는 것이다. 그러나 이것은 사실상 불가능하다. 그 이유는 바로 위에 적은대로 assetPrefix
가 globally 적용되기 때문.
2-1번 방법: CSS 파일에 있는 모든 url('/images'
를 '모두찾아바꾸기'를 이용해 하도코딩 형식으로 전부 url('https://cdn.example.co.kr/files/x2bee-fo-cdn/public/images
로 바꾸는 방법이다. 이 방법은 동작은 하겠지만 퍼블리셔들이 코드를 추가할 때 불만이 쌓일 수도 있겠다.
2-2번 방법: 위 1번 방법이 동작하지 않은 이유는 Next.js에 내장된 자체 CSS loader때문이다. 이를 customizing해서 '.css'파일의 코드를 전혀 수정하지 일괄적으로 한 방에 prefix를 붙여주기 위해서는 아래 방법대로 하면 된다.
적용
postcss-url 설치.
pnpm add --save-dev postcss-url
postcss.config.js
에 다음 코드를 추가
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
'postcss-url': {
url: ({ url }) => {
if (process.env.APP_ENV === 'stage' && url.startsWith('/images/')) {
return `https://cdn.example.co.kr/stg_files/x2bee-fo-cdn/public${url}`
} else if (
process.env.APP_ENV === 'production' &&
url.startsWith('/images/')
) {
return `https://cdn.example.co.kr/files/x2bee-fo-cdn/public${url}`
}
return url
}
}
}
}
(물론 실제로 적용된 코드는 위에 url을 '.env'에 넣어서 더 refactoring을 하였으나 위 코드가 이해가 더 쉽게 때문에 풀어썼다.)
결론
너무 복잡하게 설명했지만, 위와 같이 해주면 결국 .css 파일의 경로 코드를 수정하지 않고
내가 원하는 url에 public 폴더의 이미지들을 바라보게 할 수 있다.
'DevOps와 Infra > DevOps 일반' 카테고리의 다른 글
WhaTap 모니터링 적용해보기 (3) - NestJS (0) | 2025.02.18 |
---|---|
WhaTap 모니터링 적용해보기 (2) - Next.js (0) | 2025.02.18 |
WhaTap 모니터링 적용해보기 (1) (1) | 2025.02.13 |
K8s에 Next.js CDN 구성과 무중단 배포 전략 (1) (0) | 2025.02.11 |
K8s에 Next.js CDN 구성과 무중단 배포 전략 (2) (0) | 2025.02.04 |