diff --git a/config/nginx_project.conf.template b/config/nginx_project.conf.template index c89de7f..cba91ef 100644 --- a/config/nginx_project.conf.template +++ b/config/nginx_project.conf.template @@ -11,12 +11,15 @@ location ^~ /{{HOST}}/ { fastcgi_pass 127.0.0.1:{{PHP_PORT}}; fastcgi_index index.php; - # Correctly use $request_filename for alias compatibility - include "{{CONF_DIR}}/fastcgi_params"; - fastcgi_param SCRIPT_FILENAME $request_filename; - fastcgi_param DOCUMENT_ROOT $document_root; + # Split path info to handle subdirectories correctly + fastcgi_split_path_info ^/{{HOST}}(.+\.php)(.*)$; - # Optional parameters for frameworks + include "{{CONF_DIR}}/fastcgi_params"; + + # Bulletproof SCRIPT_FILENAME: combine base path with relative script name from split_path_info + # On Windows + Alias, $request_filename can be flaky during try_files redirects + fastcgi_param SCRIPT_FILENAME "{{PATH}}$fastcgi_script_name"; + fastcgi_param DOCUMENT_ROOT "{{PATH}}"; fastcgi_param PATH_INFO $fastcgi_path_info; } } diff --git a/src/main/ipc/index.ts b/src/main/ipc/index.ts index db1dfc3..9a756fd 100644 --- a/src/main/ipc/index.ts +++ b/src/main/ipc/index.ts @@ -56,12 +56,26 @@ async function rebuildNginxConfig(forceProjects: boolean = false): Promise<{ bin const projects = await projectService.getProjects() for (const p of projects) { const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`) - if (forceProjects || !fs.existsSync(projectConfPath)) { + let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath) + + // If file exists, check if it was manually edited + if (!shouldGenerate && fs.existsSync(projectConfPath)) { + const currentContent = fs.readFileSync(projectConfPath, 'utf8') + if (currentContent.includes('# MANUAL_EDIT')) { + shouldGenerate = false // Never overwrite manual edits during auto-rebuild + } else if (forceProjects) { + shouldGenerate = true + } + } + + if (shouldGenerate) { const phpPort = portMappingService.getPhpPort(p.phpVersion) const normalizedPath = p.path.replace(/\\/g, '/') + // Ensure path ends with a slash for alias compatibility + const pathWithSlash = normalizedPath.endsWith('/') ? normalizedPath : `${normalizedPath}/` await configService.generateConfig('nginx_project.conf.template', `projects/${p.host}.conf`, { HOST: p.host, - PATH: normalizedPath, + PATH: pathWithSlash, PHP_PORT: phpPort.toString(), CONF_DIR: confDir.replace(/\\/g, '/') }) @@ -510,8 +524,12 @@ export function registerIpcHandlers(): void { ipcMain.handle('project:nginx:save', async (_event, host, content) => { const configPath = path.join(configService.getBasePath(), 'generated_configs', 'projects', `${host}.conf`) - fs.writeFileSync(configPath, content) - // Full restart after manual project save + // Ensure manual edit marker is present + let finalContent = content + if (!finalContent.includes('# MANUAL_EDIT')) { + finalContent = `# MANUAL_EDIT\n${finalContent}` + } + fs.writeFileSync(configPath, finalContent) return await restartNginx() })