...
This commit is contained in:
@@ -11,6 +11,6 @@ FROM nginx:stable-alpine
|
|||||||
# 빌드된 파일들을 Nginx의 기본 경로로 복사
|
# 빌드된 파일들을 Nginx의 기본 경로로 복사
|
||||||
COPY --from=build /app/dist /usr/share/nginx/html
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
# (선택) 커스텀 nginx 설정을 넣고 싶다면 아래 주석 해제
|
# (선택) 커스텀 nginx 설정을 넣고 싶다면 아래 주석 해제
|
||||||
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
@@ -104,16 +104,33 @@ function startServer() {
|
|||||||
const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`);
|
const parsedUrl = new URL(req.url, `http://${req.headers.host || 'localhost'}`);
|
||||||
let requestPath = parsedUrl.pathname;
|
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
|
// Check for 'dist' in multiple locations:
|
||||||
const relativePath = requestPath.startsWith('/') ? requestPath.slice(1) : requestPath;
|
// 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);
|
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
|
// Prevent directory traversal
|
||||||
const distRoot = path.join(__dirname, 'dist');
|
|
||||||
if (!filePath.startsWith(distRoot)) {
|
if (!filePath.startsWith(distRoot)) {
|
||||||
console.log(`[Security Block] ${filePath} is outside ${distRoot}`);
|
console.log(`[Security Block] ${filePath} is outside ${distRoot}`);
|
||||||
res.writeHead(403);
|
res.writeHead(403);
|
||||||
@@ -128,8 +145,9 @@ function startServer() {
|
|||||||
if (err) {
|
if (err) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
// SPA fallback: serve index.html for unknown paths (if not an asset)
|
// SPA fallback: serve index.html for unknown paths (if not an asset)
|
||||||
|
// Use the same distRoot determined above
|
||||||
if (!extname || extname === '.html') {
|
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) {
|
if (err2) {
|
||||||
res.writeHead(404);
|
res.writeHead(404);
|
||||||
res.end('404 Not Found');
|
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