refactor: all
This commit is contained in:
+111
-15
@@ -4,7 +4,15 @@ server {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
# Gzip compression
|
||||
# 에러 페이지 설정
|
||||
error_page 404 /index.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
# 로깅 설정
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
# Gzip compression 최적화
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
@@ -17,30 +25,118 @@ server {
|
||||
text/javascript
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/json;
|
||||
application/json
|
||||
application/xml
|
||||
image/svg+xml;
|
||||
|
||||
# Handle client routing (Vue Router)
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
# Brotli compression (더 좋은 압축률)
|
||||
# brotli on;
|
||||
# brotli_comp_level 6;
|
||||
# brotli_types text/xml image/svg+xml application/x-font-ttf image/vnd.microsoft.icon application/x-font-opentype application/json font/eot application/vnd.ms-fontobject application/javascript font/otf application/xml application/xhtml+xml text/javascript application/x-javascript text/plain application/x-font-truetype application/xml+rss image/x-icon font/opentype text/css image/x-win-bitmap;
|
||||
|
||||
# Security headers
|
||||
# 보안 헤더 강화
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://fonts.googleapis.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' http://smarketing.20.249.184.228.nip.io https://smarketing.20.249.184.228.nip.io" always;
|
||||
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
# CORS 설정 (필요시)
|
||||
add_header Access-Control-Allow-Origin "*" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
|
||||
|
||||
# SPA 라우팅 처리 (Vue Router)
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# HTML 파일은 캐시하지 않음 (런타임 설정 반영 위해)
|
||||
location ~* \.html$ {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
}
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
# 런타임 환경 설정 파일 - 캐시하지 않음
|
||||
location /runtime-env.js {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
}
|
||||
|
||||
# 정적 자산 캐시 최적화
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
|
||||
# 정적 파일에 대한 로깅 최소화
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# manifest.json과 service worker 캐시 설정
|
||||
location ~* \.(json|webmanifest)$ {
|
||||
expires 1d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location /sw.js {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
}
|
||||
|
||||
# 파비콘 캐시
|
||||
location /favicon.ico {
|
||||
expires 1M;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 헬스체크 엔드포인트
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
|
||||
# API 프록시 (필요시 백엔드로 직접 프록시)
|
||||
# location /api/ {
|
||||
# proxy_pass http://smarketing.20.249.184.228.nip.io/api/;
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# proxy_connect_timeout 30s;
|
||||
# proxy_send_timeout 30s;
|
||||
# proxy_read_timeout 30s;
|
||||
# }
|
||||
|
||||
# 숨겨진 파일 접근 차단
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 불필요한 파일 접근 차단
|
||||
location ~* \.(log|txt|md|yml|yaml|conf)$ {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# 압축된 자산 우선 제공
|
||||
location ~* \.(js|css)$ {
|
||||
gzip_static on;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
|
||||
# 추가 서버 블록 (HTTPS 리다이렉트, 필요시)
|
||||
# server {
|
||||
# listen 8080;
|
||||
# server_name smarketing.20.249.184.228.nip.io;
|
||||
# return 301 https://$server_name$request_uri;
|
||||
# }
|
||||
@@ -140,7 +140,7 @@ metadata:
|
||||
labels:
|
||||
app: smarketing-frontend
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: ${export_port}
|
||||
@@ -157,6 +157,7 @@ metadata:
|
||||
namespace: ${namespace}
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
spec:
|
||||
rules:
|
||||
- host: ${ingress_host}
|
||||
|
||||
@@ -14,14 +14,14 @@ export_port=18080
|
||||
# Gateway/Ingress 설정 (⭐ smarketing-backend와 동일한 IP 사용)
|
||||
ingress_host=smarketing.20.249.184.228.nip.io
|
||||
|
||||
# 리소스 설정
|
||||
resources_requests_cpu=256m
|
||||
resources_requests_memory=256Mi
|
||||
resources_limits_cpu=1024m
|
||||
resources_limits_memory=1024Mi
|
||||
# 리소스 설정 (프론트엔드에 맞게 조정)
|
||||
resources_requests_cpu=128m # 프론트엔드는 CPU 사용량이 적음
|
||||
resources_requests_memory=128Mi # 메모리도 적게 사용
|
||||
resources_limits_cpu=512m # 제한도 낮게 설정
|
||||
resources_limits_memory=512Mi
|
||||
|
||||
# API URLs (⭐ smarketing-backend ingress를 통해 라우팅)
|
||||
# 현재 설정된 백엔드 API들과 일치
|
||||
# 백엔드 서비스별 API 경로들
|
||||
auth_url=http://smarketing.20.249.184.228.nip.io/api/auth
|
||||
member_url=http://smarketing.20.249.184.228.nip.io/api/member
|
||||
store_url=http://smarketing.20.249.184.228.nip.io/api/store
|
||||
@@ -30,6 +30,39 @@ sales_url=http://smarketing.20.249.184.228.nip.io/api/sales
|
||||
content_url=http://smarketing.20.249.184.228.nip.io/api/content
|
||||
recommend_url=http://smarketing.20.249.184.228.nip.io/api/recommend
|
||||
|
||||
# Frontend 이미지 경로 설정
|
||||
smarketing_frontend_image_path=${registry}/${image_org}/smarketing-frontend:latest
|
||||
|
||||
# GitHub 설정
|
||||
github_org=won-ktds
|
||||
teamid=smarketing
|
||||
teamid=smarketing
|
||||
|
||||
# 환경 플래그
|
||||
environment=production
|
||||
debug_mode=false
|
||||
|
||||
# SSL/TLS 설정 (필요시)
|
||||
ssl_enabled=false
|
||||
ssl_redirect=false
|
||||
|
||||
# 로깅 레벨
|
||||
log_level=info
|
||||
|
||||
# 헬스체크 설정
|
||||
health_check_path=/health
|
||||
health_check_interval=30s
|
||||
health_check_timeout=5s
|
||||
health_check_retries=3
|
||||
|
||||
# 보안 설정
|
||||
security_headers_enabled=true
|
||||
cors_enabled=true
|
||||
allowed_origins=*
|
||||
|
||||
# 캐시 설정
|
||||
static_cache_enabled=true
|
||||
static_cache_duration=1y
|
||||
|
||||
# 압축 설정
|
||||
gzip_enabled=true
|
||||
gzip_compression_level=6
|
||||
@@ -5,6 +5,7 @@ metadata:
|
||||
namespace: ${namespace}
|
||||
labels:
|
||||
app: smarketing-frontend
|
||||
version: v1
|
||||
spec:
|
||||
replicas: ${replicas}
|
||||
selector:
|
||||
@@ -14,6 +15,7 @@ spec:
|
||||
metadata:
|
||||
labels:
|
||||
app: smarketing-frontend
|
||||
version: v1
|
||||
spec:
|
||||
imagePullSecrets:
|
||||
- name: acr-secret
|
||||
@@ -23,6 +25,7 @@ spec:
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: ${export_port}
|
||||
name: http
|
||||
resources:
|
||||
requests:
|
||||
cpu: ${resources_requests_cpu}
|
||||
@@ -34,19 +37,53 @@ spec:
|
||||
- name: runtime-config
|
||||
mountPath: /usr/share/nginx/html/runtime-env.js
|
||||
subPath: runtime-env.js
|
||||
readOnly: true
|
||||
env:
|
||||
- name: NGINX_PORT
|
||||
value: "${export_port}"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: ${export_port}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: ${export_port}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
# 시작 프로브 추가 (컨테이너 시작 시간이 오래 걸릴 수 있음)
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: ${export_port}
|
||||
scheme: HTTP
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 30
|
||||
successThreshold: 1
|
||||
volumes:
|
||||
- name: runtime-config
|
||||
configMap:
|
||||
name: smarketing-frontend-config
|
||||
name: smarketing-frontend-config
|
||||
defaultMode: 0644
|
||||
# 배포 전략 설정
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
# 재시작 정책
|
||||
restartPolicy: Always
|
||||
# DNS 정책
|
||||
dnsPolicy: ClusterFirst
|
||||
@@ -8,14 +8,14 @@ data:
|
||||
console.log('=== RUNTIME-ENV.JS 로드됨 (배포 환경) ===');
|
||||
|
||||
window.__runtime_config__ = {
|
||||
// 백엔드 API 구조에 맞게 URL 설정
|
||||
// 백엔드 API 구조에 맞게 URL 설정 - ingress host 사용
|
||||
AUTH_URL: 'http://${ingress_host}/api/auth',
|
||||
MEMBER_URL: 'http://${ingress_host}/api/member',
|
||||
STORE_URL: 'http://${ingress_host}/api/store',
|
||||
MENU_URL: 'http://${ingress_host}/api/menu',
|
||||
SALES_URL: 'http://${ingress_host}/api/sales',
|
||||
CONTENT_URL: 'http://${ingress_host}/api/content',
|
||||
RECOMMEND_URL: 'http://${ingress_host}/api/recommendations',
|
||||
RECOMMEND_URL: 'http://${ingress_host}/api/recommend',
|
||||
|
||||
// Gateway URL (운영 환경)
|
||||
GATEWAY_URL: 'http://${ingress_host}',
|
||||
|
||||
Reference in New Issue
Block a user