정적 리소스 서빙 및 빌드 프로세스 개선:
- OHS 환경 대응 정적자원 해시 버전닝 OFF 설정 반영 - eapim-portal-static.zip 생성 및 CI/CD 추가 - OHS 설정 샘플 가이드 추가
This commit is contained in:
+2
-1
@@ -74,8 +74,9 @@ pipeline {
|
|||||||
set -eu
|
set -eu
|
||||||
cd build/libs
|
cd build/libs
|
||||||
sha256sum eapim-portal.war > eapim-portal.war.sha256
|
sha256sum eapim-portal.war > eapim-portal.war.sha256
|
||||||
|
sha256sum eapim-portal-static.zip > eapim-portal-static.zip.sha256
|
||||||
'''
|
'''
|
||||||
archiveArtifacts artifacts: 'build/libs/eapim-portal.war,build/libs/eapim-portal.war.sha256', fingerprint: true
|
archiveArtifacts artifacts: 'build/libs/eapim-portal.war,build/libs/eapim-portal.war.sha256,build/libs/eapim-portal-static.zip,build/libs/eapim-portal-static.zip.sha256', fingerprint: true
|
||||||
stash name: 'war', includes: 'build/libs/eapim-portal.war'
|
stash name: 'war', includes: 'build/libs/eapim-portal.war'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,8 +96,9 @@ pipeline {
|
|||||||
sha256sum "$f" > "$f.sha256"
|
sha256sum "$f" > "$f.sha256"
|
||||||
md5sum "$f" > "$f.md5"
|
md5sum "$f" > "$f.md5"
|
||||||
done
|
done
|
||||||
|
sha256sum eapim-portal-static.zip > eapim-portal-static.zip.sha256
|
||||||
'''
|
'''
|
||||||
archiveArtifacts artifacts: 'build/libs/eapim-portal.war,build/libs/eapim-portal-boot.war,build/libs/eapim-portal.war.sha1,build/libs/eapim-portal.war.sha256,build/libs/eapim-portal.war.md5,build/libs/eapim-portal-boot.war.sha1,build/libs/eapim-portal-boot.war.sha256,build/libs/eapim-portal-boot.war.md5', fingerprint: true
|
archiveArtifacts artifacts: 'build/libs/eapim-portal.war,build/libs/eapim-portal-boot.war,build/libs/eapim-portal.war.sha1,build/libs/eapim-portal.war.sha256,build/libs/eapim-portal.war.md5,build/libs/eapim-portal-boot.war.sha1,build/libs/eapim-portal-boot.war.sha256,build/libs/eapim-portal-boot.war.md5,build/libs/eapim-portal-static.zip,build/libs/eapim-portal-static.zip.sha256', fingerprint: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -315,6 +315,18 @@ war {
|
|||||||
classpath = excludeLocalOnlyLibs(classpath)
|
classpath = excludeLocalOnlyLibs(classpath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 정적 리소스만 별도 zip (OHS 추가 배포용). war/bootWar 는 그대로 정적 리소스 포함 유지
|
||||||
|
// (WAS 단독 접속 인원 지원). sass/ 는 컴파일 소스이며 실제 서빙 경로에 없어 제외
|
||||||
|
// (PortalConfigWebDispatcherServlet#addResourceHandlers 기준).
|
||||||
|
task staticResourcesZip(type: Zip) {
|
||||||
|
archiveFileName = "eapim-portal-static.zip"
|
||||||
|
destinationDirectory = file("$buildDir/libs")
|
||||||
|
from('src/main/resources/static') {
|
||||||
|
exclude 'sass/**'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assemble.dependsOn staticResourcesZip
|
||||||
|
|
||||||
task printSourceSets {
|
task printSourceSets {
|
||||||
doLast {
|
doLast {
|
||||||
sourceSets.each { srcSet ->
|
sourceSets.each { srcSet ->
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
## OHS Static Resource 설정 예시
|
||||||
|
|
||||||
|
```apacheconf
|
||||||
|
<VirtualHost *:443>
|
||||||
|
ServerName weblogic-djb.rinjae.kr
|
||||||
|
|
||||||
|
<IfModule ossl_module>
|
||||||
|
SSLEngine on
|
||||||
|
SSLVerifyClient None
|
||||||
|
SSLProtocol TLSv1.2 TLSv1.3
|
||||||
|
SSLHonorCipherOrder on
|
||||||
|
SSLCipherSuite TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_CHACHA20_POLY1305_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
SSLWallet "${ORACLE_INSTANCE}/config/fmwconfig/components/${COMPONENT_TYPE}/instances/${COMPONENT_NAME}/keystores/default"
|
||||||
|
|
||||||
|
<FilesMatch "\.(cgi|shtml|phtml|php)$">
|
||||||
|
SSLOptions +StdEnvVars
|
||||||
|
</FilesMatch>
|
||||||
|
|
||||||
|
<Directory "${ORACLE_INSTANCE}/config/fmwconfig/components/${COMPONENT_TYPE}/instances/${COMPONENT_NAME}/cgi-bin">
|
||||||
|
SSLOptions +StdEnvVars
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
BrowserMatch "MSIE [2-5]" \
|
||||||
|
nokeepalive ssl-unclean-shutdown \
|
||||||
|
downgrade-1.0 force-response-1.0
|
||||||
|
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
Header always set Strict-Transport-Security "max-age=63072000; preload; includeSubDomains"
|
||||||
|
</IfModule>
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
Alias /css /ohs/static/eapim-portal/css
|
||||||
|
Alias /js /ohs/static/eapim-portal/js
|
||||||
|
Alias /img /ohs/static/eapim-portal/img
|
||||||
|
Alias /images /ohs/static/eapim-portal/images
|
||||||
|
Alias /webfonts /ohs/static/eapim-portal/webfonts
|
||||||
|
Alias /font /ohs/static/eapim-portal/font
|
||||||
|
Alias /html /ohs/static/eapim-portal/html
|
||||||
|
Alias /plugins /ohs/static/eapim-portal/plugins
|
||||||
|
|
||||||
|
<Directory "/ohs/static/eapim-portal">
|
||||||
|
Require all granted
|
||||||
|
Options -Indexes
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<LocationMatch "^/(css|js|img|images|webfonts|font|html|plugins)/">
|
||||||
|
Header set Cache-Control "no-cache"
|
||||||
|
</LocationMatch>
|
||||||
|
|
||||||
|
<IfModule weblogic_module>
|
||||||
|
<Location />
|
||||||
|
DirectoryIndex disabled
|
||||||
|
SetHandler weblogic-handler
|
||||||
|
WebLogicHost 172.30.1.100
|
||||||
|
WebLogicPort 39130
|
||||||
|
DynamicServerList OFF
|
||||||
|
ConnectTimeoutSecs 10
|
||||||
|
ConnectRetrySecs 2
|
||||||
|
WLProxySSL ON
|
||||||
|
</Location>
|
||||||
|
</IfModule>
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
```
|
||||||
+24
-11
@@ -175,31 +175,44 @@ public class PortalConfigWebDispatcherServlet implements WebMvcConfigurer {
|
|||||||
* {@code /css/main.css} 요청을 내용 해시가 포함된 {@code /css/main-<hash>.css} 로 매핑한다.
|
* {@code /css/main.css} 요청을 내용 해시가 포함된 {@code /css/main-<hash>.css} 로 매핑한다.
|
||||||
* 내용이 바뀌면 URL 이 바뀌므로 강제 새로고침 없이 브라우저 캐시가 무효화된다. Thymeleaf 의
|
* 내용이 바뀌면 URL 이 바뀌므로 강제 새로고침 없이 브라우저 캐시가 무효화된다. Thymeleaf 의
|
||||||
* {@code @{/css/main.css}} 링크는 {@link #resourceUrlEncodingFilter()} 가 해시 URL 로 치환한다.</p>
|
* {@code @{/css/main.css}} 링크는 {@link #resourceUrlEncodingFilter()} 가 해시 URL 로 치환한다.</p>
|
||||||
|
*
|
||||||
|
* <p>버전닝이 꺼져 있으면(prod 포함 — {@link #isResourceVersioningEnabled()} 참고) URL 이
|
||||||
|
* 고정이라 장기 {@code max-age} 캐시를 쓰면 배포 후에도 브라우저가 옛 내용을 계속 쓸 위험이 있다.
|
||||||
|
* 이 경우 {@code no-cache}(매 요청 {@code If-Modified-Since} 조건부 재검증, 변경 없으면 304)로
|
||||||
|
* 신선도를 보장한다 — OHS 가 정적 리소스를 직접 서빙해도 Apache 가 파일 mtime 기준으로 동일하게
|
||||||
|
* Last-Modified/조건부 GET 을 처리하므로 WAS 와 동작이 어긋나지 않는다
|
||||||
|
* (배경: djb-obsidian-docs/3000-테스트/15-Static리소스분리).</p>
|
||||||
*/
|
*/
|
||||||
private void addStaticResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
|
private void addStaticResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
|
||||||
// 캐싱 ON(prod) 이면 브라우저에 1일 캐시를, OFF(dev/local) 면 no-store 를 내려보낸다.
|
boolean versioningOn = isResourceVersioningEnabled();
|
||||||
// no-store 는 브라우저가 아예 저장하지 않으므로 강제 새로고침 없이 sass/JS 변경이 바로 보인다.
|
CacheControl cacheControl;
|
||||||
CacheControl cacheControl = isResourceCachingEnabled()
|
if (!isResourceCachingEnabled()) {
|
||||||
? CacheControl.maxAge(1, TimeUnit.DAYS)
|
// no-store: 브라우저가 아예 저장하지 않으므로 강제 새로고침 없이 sass/JS 변경이 바로 보인다(dev/local).
|
||||||
: CacheControl.noStore();
|
cacheControl = CacheControl.noStore();
|
||||||
|
} else if (versioningOn) {
|
||||||
|
cacheControl = CacheControl.maxAge(1, TimeUnit.DAYS);
|
||||||
|
} else {
|
||||||
|
cacheControl = CacheControl.noCache();
|
||||||
|
}
|
||||||
ResourceChainRegistration chain = registry.addResourceHandler(pattern)
|
ResourceChainRegistration chain = registry.addResourceHandler(pattern)
|
||||||
.addResourceLocations(locations)
|
.addResourceLocations(locations)
|
||||||
.setCacheControl(cacheControl)
|
.setCacheControl(cacheControl)
|
||||||
.resourceChain(isResourceCachingEnabled());
|
.resourceChain(isResourceCachingEnabled());
|
||||||
if (isResourceVersioningEnabled()) {
|
if (versioningOn) {
|
||||||
chain.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
|
chain.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"));
|
||||||
}
|
}
|
||||||
chain.addResolver(new PathResourceResolver());
|
chain.addResolver(new PathResourceResolver());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 정적자원 해시 버전닝 활성 여부. prod 프로파일은 토글과 무관하게 항상 ON,
|
* 정적자원 해시 버전닝 활성 여부. {@code app.resource-versioning.enabled} 값을 그대로 따른다.
|
||||||
* 그 외 프로파일은 {@code app.resource-versioning.enabled} 값을 따른다.
|
*
|
||||||
|
* <p>과거 prod 프로파일은 이 토글과 무관하게 항상 ON 이었으나, OHS 가 정적 리소스를 직접
|
||||||
|
* 서빙하는 구조로 바뀌면서 OFF 로 전환했다 — 해시가 붙은 URL(main-<hash>.css)이 OHS
|
||||||
|
* 디스크의 무해시 원본과 어긋나 404 가 날 수 있어서다(prod.yml 에서 명시적으로 false 설정).
|
||||||
|
* 대신 캐시 신선도는 {@link #addStaticResourceHandler} 의 no-cache 조건부 재검증으로 보장한다.</p>
|
||||||
*/
|
*/
|
||||||
private boolean isResourceVersioningEnabled() {
|
private boolean isResourceVersioningEnabled() {
|
||||||
if (environment.acceptsProfiles(Profiles.of("prod"))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return resourceVersioningEnabled;
|
return resourceVersioningEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ spring:
|
|||||||
cachecontrol:
|
cachecontrol:
|
||||||
max-age: 86400
|
max-age: 86400
|
||||||
public: true
|
public: true
|
||||||
# 정적자원 콘텐츠 해시 버전닝은 PortalConfigWebDispatcherServlet 가 prod 프로파일에서
|
# 정적자원 콘텐츠 해시 버전닝: OHS 가 정적 리소스(css/js/img 등)를 직접 서빙하는 구조에서는
|
||||||
# 항상 ON 으로 수행한다(app.resource-versioning.enabled 토글 무시).
|
# 해시 URL(main-<hash>.css)이 OHS 디스크의 무해시 원본과 어긋나 404 위험이 있어 OFF 로 전환했다
|
||||||
# 해시 URL + 장기 캐시(max-age 86400)로 배포 시 자동 캐시 무효화.
|
# (아래 app.resource-versioning.enabled: false, PortalConfigWebDispatcherServlet 참고).
|
||||||
|
# 캐시 무효화는 대신 no-cache(매 요청 If-Modified-Since 조건부 재검증)로 보장한다.
|
||||||
|
# 배경: djb-obsidian-docs/3000-테스트/15-Static리소스분리
|
||||||
jpa:
|
jpa:
|
||||||
properties:
|
properties:
|
||||||
hibernate:
|
hibernate:
|
||||||
@@ -28,7 +30,7 @@ spring:
|
|||||||
|
|
||||||
app:
|
app:
|
||||||
resource-versioning:
|
resource-versioning:
|
||||||
enabled: true
|
enabled: false
|
||||||
resource-caching:
|
resource-caching:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user