...
This commit is contained in:
@@ -11,6 +11,6 @@ FROM nginx:stable-alpine
|
||||
# 빌드된 파일들을 Nginx의 기본 경로로 복사
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
# (선택) 커스텀 nginx 설정을 넣고 싶다면 아래 주석 해제
|
||||
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -104,16 +104,33 @@ function startServer() {
|
||||
const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`);
|
||||
let requestPath = parsedUrl.pathname;
|
||||
|
||||
if (requestPath === '/') requestPath = '/index.html';
|
||||
// Check for 'dist' in multiple locations:
|
||||
// 1. External 'dist' next to executable (Priority for updates/deployment)
|
||||
// 2. Internal 'dist' (Bundled in pkg or source)
|
||||
|
||||
// Remove leading slash for path.join to work relatively
|
||||
const relativePath = requestPath.startsWith('/') ? requestPath.slice(1) : requestPath;
|
||||
// Check for 'dist' in multiple locations:
|
||||
// 1. External 'dist' next to executable (Priority for updates/deployment)
|
||||
// 2. Internal 'dist' (Bundled in pkg or source)
|
||||
|
||||
const pathName = parsedUrl.pathname === '/' ? '/index.html' : parsedUrl.pathname;
|
||||
const relativePath = pathName.startsWith('/') ? pathName.slice(1) : pathName;
|
||||
const decodedPath = decodeURIComponent(relativePath);
|
||||
let filePath = path.join(__dirname, 'dist', decodedPath);
|
||||
|
||||
let distRoot;
|
||||
let filePath;
|
||||
|
||||
const externalDist = path.join(path.dirname(process.execPath), 'dist');
|
||||
const internalDist = path.join(__dirname, 'dist');
|
||||
|
||||
if (fs.existsSync(externalDist)) {
|
||||
distRoot = externalDist;
|
||||
filePath = path.join(externalDist, decodedPath);
|
||||
} else {
|
||||
distRoot = internalDist;
|
||||
filePath = path.join(internalDist, decodedPath);
|
||||
}
|
||||
|
||||
// Prevent directory traversal
|
||||
const distRoot = path.join(__dirname, 'dist');
|
||||
if (!filePath.startsWith(distRoot)) {
|
||||
console.log(`[Security Block] ${filePath} is outside ${distRoot}`);
|
||||
res.writeHead(403);
|
||||
@@ -128,8 +145,9 @@ function startServer() {
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
// SPA fallback: serve index.html for unknown paths (if not an asset)
|
||||
// Use the same distRoot determined above
|
||||
if (!extname || extname === '.html') {
|
||||
fs.readFile(path.join(__dirname, 'dist', 'index.html'), (err2, content2) => {
|
||||
fs.readFile(path.join(distRoot, 'index.html'), (err2, content2) => {
|
||||
if (err2) {
|
||||
res.writeHead(404);
|
||||
res.end('404 Not Found');
|
||||
|
||||
22
nginx.conf
Normal file
22
nginx.conf
Normal file
@@ -0,0 +1,22 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# Gzip settings for better performance
|
||||
gzip on;
|
||||
gzip_min_length 1000;
|
||||
gzip_proxied expired no-cache no-store private auth;
|
||||
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Handle assets correctly to avoid fallback to index.html for missing files
|
||||
location /assets/ {
|
||||
try_files $uri =404;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user