v4.0.8: nginx no-cache·deck-favorites shim으로 배포/캐시 문제 수정

구 HTML·CDN immutable JS가 init 없이 남던 문제를 nginx 캐시 정책·shim·배포 검증으로 해결한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 16:24:19 +09:00
parent 72d73a54bd
commit eb4b35bccc
8 changed files with 100 additions and 20 deletions

View File

@@ -1 +1 @@
v4.0.7
v4.0.8

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4516420168710424" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./style/output.css?v=4.0.7" />
<link rel="stylesheet" href="./style/output.css?v=4.0.8" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet" />
<title>내 덱 관리 - UNIARE</title>
</head>
@@ -76,13 +76,14 @@
</div>
</div>
<script src="/script/api.js?v=4.0.7"></script>
<script src="/script/ads.js?v=4.0.7"></script>
<script src="/script/deck-favorites.js?v=4.0.7"></script>
<script src="/script/deck-preview-hold.js?v=4.0.7"></script>
<script src="/script/page-i18n.js?v=4.0.7"></script>
<script src="/script/page-help.js?v=4.0.7"></script>
<script src="/script/auth-header.js?v=4.0.7"></script>
<script src="/script/api.js?v=4.0.8"></script>
<script src="/script/ads.js?v=4.0.8"></script>
<script src="/script/deck-favorites.js?v=4.0.8"></script>
<script src="/script/deck-favorites-shim.js?v=4.0.8"></script>
<script src="/script/deck-preview-hold.js?v=4.0.8"></script>
<script src="/script/page-i18n.js?v=4.0.8"></script>
<script src="/script/page-help.js?v=4.0.8"></script>
<script src="/script/auth-header.js?v=4.0.8"></script>
<script>
/** @type {Array<object>} */
let allDecks = [];

View File

@@ -59,6 +59,7 @@ services:
- ./i18n:/usr/share/nginx/html/i18n:ro
- ./datas:/usr/share/nginx/html/datas:ro
- ./images:/usr/share/nginx/html/images:ro
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
uniare-api:
condition: service_healthy

View File

@@ -118,7 +118,29 @@ head -1 login.html # output.css?v= 버전 쿼리 포함 여부
`script/deck-favorites.js`는 `window.UaDeckFavorites.init`이 있어야 한다. 없으면 `git pull` 누락 또는 JS CDN 캐시다.
`nginx/default.conf`를 변경했다면 `docker compose -f docker-compose.prod.yml up -d --build uniare-web`으로 웹 컨테이너만 재빌드한다. HTML·`style/`·`script/`만 바뀐 경우 컨테이너 재시작은 필요 없다.
`nginx/default.conf`를 변경했다면 **반드시** 웹 컨테이너를 재생성한다 (볼륨 마운트 반영):
```bash
docker compose -f docker-compose.prod.yml up -d --build uniare-web
```
배포 검증 (NAS 프로젝트 폴더):
```bash
# 호스트 파일 — v4.0.8·shim 포함 여부
rg "4\.0\.8|deck-favorites-shim" deckHistory.html
# 컨테이너가 같은 파일을 보는지 (다르면 compose 경로/마운트 문제)
docker exec uniare-web rg "deck-favorites-shim|4\.0\.8" /usr/share/nginx/html/deckHistory.html
# Docker 직접 접속 (Cloudflare 우회) — 위와 같아야 함
curl -s http://127.0.0.1:44082/deckHistory.html | rg "deck-favorites-shim|4\.0\.8"
curl -s http://127.0.0.1:44082/script/deck-favorites.js | tail -1
```
호스트·컨테이너·`curl 127.0.0.1`은 최신인데 `https://uniare.sori.studio`만 구버전이면 **Cloudflare 캐시 Purge**가 필요하다.
HTML·`style/`·`script/`만 바뀐 경우 API 컨테이너 재시작은 필요 없다.
## 4. 전체 업데이트

View File

@@ -1,5 +1,14 @@
# 업데이트 이력
## 2026-06-23 / v4.0.8 — nginx 정적 캐시·deck-favorites 배포 수정
### 수행 작업
- 운영 HTML이 v4.0.6·JS가 CDN `immutable` 구버전으로 남아 `init` 오류 지속
- `docker-compose.prod.yml`: `nginx/default.conf` 볼륨 마운트 추가
- nginx: HTML·`deck-favorites.js`·`api.js` `no-cache`, JS `immutable` 제거
- `script/deck-favorites-shim.js`: 구버전 JS에 `init`/`forget` 폴리해
- `docs/deploy.md`: 호스트 vs 컨테이너 vs Cloudflare 3단계 검증 명령 추가
## 2026-06-23 / v4.0.7 — 덱 목록 JS 캐시·init 오류 수정
### 수행 작업

View File

@@ -23,6 +23,23 @@ server {
client_max_body_size 25m;
}
# HTML — 배포 직후 반영
location ~* \.html$ {
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri =404;
}
# 핵심 JS — 구 URL(?v= 없음)도 최신 파일 제공 (CDN immutable 회피)
location = /script/deck-favorites.js {
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri =404;
}
location = /script/api.js {
add_header Cache-Control "no-cache, must-revalidate";
try_files $uri =404;
}
# CSS — 배포 후 즉시 반영 (immutable 사용 안 함)
location ~* \.css$ {
expires 1h;
@@ -30,8 +47,15 @@ server {
try_files $uri =404;
}
# 기타 정적 자산
location ~* \.(js|png|jpg|jpeg|gif|webp|ico|svg|woff2?)$ {
# JS — immutable 제거 (이미지보다 짧게 재검증)
location ~* \.js$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
try_files $uri =404;
}
# 이미지 등
location ~* \.(png|jpg|jpeg|gif|webp|ico|svg|woff2?)$ {
expires 7d;
add_header Cache-Control "public, immutable";
try_files $uri =404;

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4516420168710424" crossorigin="anonymous"></script>
<link rel="stylesheet" href="./style/output.css?v=4.0.7" />
<link rel="stylesheet" href="./style/output.css?v=4.0.8" />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800;900&family=Noto+Sans+KR:wght@400;700;900&display=swap" rel="stylesheet" />
<title>공개 덱 - UNIARE</title>
</head>
@@ -69,13 +69,14 @@
</div>
</div>
<script src="/script/api.js?v=4.0.7"></script>
<script src="/script/ads.js?v=4.0.7"></script>
<script src="/script/deck-favorites.js?v=4.0.7"></script>
<script src="/script/deck-preview-hold.js?v=4.0.7"></script>
<script src="/script/page-i18n.js?v=4.0.7"></script>
<script src="/script/page-help.js?v=4.0.7"></script>
<script src="/script/auth-header.js?v=4.0.7"></script>
<script src="/script/api.js?v=4.0.8"></script>
<script src="/script/ads.js?v=4.0.8"></script>
<script src="/script/deck-favorites.js?v=4.0.8"></script>
<script src="/script/deck-favorites-shim.js?v=4.0.8"></script>
<script src="/script/deck-preview-hold.js?v=4.0.8"></script>
<script src="/script/page-i18n.js?v=4.0.8"></script>
<script src="/script/page-help.js?v=4.0.8"></script>
<script src="/script/auth-header.js?v=4.0.8"></script>
<script>
/** @type {Array<object>} */
let allDecks = [];

View File

@@ -0,0 +1,22 @@
/**
* 구 CDN 캐시 deck-favorites.js(init 없음) 호환 — init/forget 폴리해
*/
(function applyDeckFavoritesShim() {
const F = window.UaDeckFavorites;
if (!F) return;
if (typeof F.init !== 'function') {
F.init = async function initLegacyShim() {
/* localStorage 전용 구버전 — 계정 동기화 없음 */
};
}
if (typeof F.forget !== 'function') {
F.forget = function forgetLegacyShim(shareCode) {
if (!shareCode || typeof F.isFavorite !== 'function') return;
if (F.isFavorite(shareCode) && typeof F.toggle === 'function') {
F.toggle(shareCode);
}
};
}
})();