feat: implement IPC handlers for Nginx and Apache configuration management and service lifecycle control
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
Define SRVROOT "{{SRVROOT}}"
|
Define SRVROOT "{{SRVROOT}}"
|
||||||
|
ServerRoot "${SRVROOT}"
|
||||||
|
|
||||||
Listen {{LISTEN_ADDRESS}}:{{PORT}}
|
Listen {{LISTEN_ADDRESS}}:{{PORT}}
|
||||||
|
|
||||||
|
# Temel Modüller
|
||||||
LoadModule authz_core_module modules/mod_authz_core.so
|
LoadModule authz_core_module modules/mod_authz_core.so
|
||||||
LoadModule authz_host_module modules/mod_authz_host.so
|
LoadModule authz_host_module modules/mod_authz_host.so
|
||||||
|
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
|
||||||
|
LoadModule authz_user_module modules/mod_authz_user.so
|
||||||
|
LoadModule authn_core_module modules/mod_authn_core.so
|
||||||
|
LoadModule authn_file_module modules/mod_authn_file.so
|
||||||
LoadModule dir_module modules/mod_dir.so
|
LoadModule dir_module modules/mod_dir.so
|
||||||
LoadModule mime_module modules/mod_mime.so
|
LoadModule mime_module modules/mod_mime.so
|
||||||
LoadModule alias_module modules/mod_alias.so
|
LoadModule alias_module modules/mod_alias.so
|
||||||
@@ -11,6 +17,17 @@ LoadModule log_config_module modules/mod_log_config.so
|
|||||||
LoadModule rewrite_module modules/mod_rewrite.so
|
LoadModule rewrite_module modules/mod_rewrite.so
|
||||||
LoadModule proxy_module modules/mod_proxy.so
|
LoadModule proxy_module modules/mod_proxy.so
|
||||||
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
|
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
|
||||||
|
LoadModule autoindex_module modules/mod_autoindex.so
|
||||||
|
LoadModule negotiation_module modules/mod_negotiation.so
|
||||||
|
LoadModule setenvif_module modules/mod_setenvif.so
|
||||||
|
# Önerilen Ek Modüller
|
||||||
|
LoadModule headers_module modules/mod_headers.so
|
||||||
|
LoadModule env_module modules/mod_env.so
|
||||||
|
LoadModule deflate_module modules/mod_deflate.so
|
||||||
|
|
||||||
|
# Windows optimizations
|
||||||
|
AcceptFilter http none
|
||||||
|
AcceptFilter https none
|
||||||
|
|
||||||
# Required for PHP-FPM on Windows to avoid "No input file specified"
|
# Required for PHP-FPM on Windows to avoid "No input file specified"
|
||||||
<IfModule proxy_fcgi_module>
|
<IfModule proxy_fcgi_module>
|
||||||
@@ -20,6 +37,15 @@ LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
|
|||||||
ServerAdmin admin@localhost
|
ServerAdmin admin@localhost
|
||||||
ServerName localhost:{{PORT}}
|
ServerName localhost:{{PORT}}
|
||||||
|
|
||||||
|
# MIME Types (Kritik)
|
||||||
|
TypesConfig conf/mime.types
|
||||||
|
|
||||||
|
# Ana Güvenlik Kuralı (Tüm disk erişimini kapat)
|
||||||
|
<Directory />
|
||||||
|
AllowOverride none
|
||||||
|
Require all denied
|
||||||
|
</Directory>
|
||||||
|
|
||||||
DocumentRoot "{{ROOT}}"
|
DocumentRoot "{{ROOT}}"
|
||||||
<Directory "{{ROOT}}">
|
<Directory "{{ROOT}}">
|
||||||
Options Indexes FollowSymLinks
|
Options Indexes FollowSymLinks
|
||||||
@@ -58,6 +84,7 @@ Alias /phpmyadmin "{{PHPMYADMIN_DIR}}"
|
|||||||
# Global PHP handler
|
# Global PHP handler
|
||||||
<FilesMatch \.php$>
|
<FilesMatch \.php$>
|
||||||
SetHandler "proxy:fcgi://127.0.0.1:{{PHP_PORT}}/"
|
SetHandler "proxy:fcgi://127.0.0.1:{{PHP_PORT}}/"
|
||||||
|
CGIPassAuth On
|
||||||
</FilesMatch>
|
</FilesMatch>
|
||||||
|
|
||||||
# Project configurations
|
# Project configurations
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ session.save_path = "{{SESSION_DIR}}"
|
|||||||
upload_tmp_dir = "{{TEMP_DIR}}"
|
upload_tmp_dir = "{{TEMP_DIR}}"
|
||||||
sys_temp_dir = "{{TEMP_DIR}}"
|
sys_temp_dir = "{{TEMP_DIR}}"
|
||||||
extension_dir = "{{EXT_DIR}}"
|
extension_dir = "{{EXT_DIR}}"
|
||||||
|
cgi.force_redirect = 0
|
||||||
|
cgi.fix_pathinfo = 1
|
||||||
|
|
||||||
[ExtensionList]
|
[ExtensionList]
|
||||||
{{EXTENSIONS}}
|
{{EXTENSIONS}}
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@
|
|||||||
"phpPort": "9001",
|
"phpPort": "9001",
|
||||||
"mariaDbPort": "3306",
|
"mariaDbPort": "3306",
|
||||||
"mariaDbPorts": {},
|
"mariaDbPorts": {},
|
||||||
"allowRemoteAccess": true,
|
"allowRemoteAccess": false,
|
||||||
"language": "tr",
|
"language": "tr",
|
||||||
"mysqlPort": "3306",
|
"mysqlPort": "3306",
|
||||||
"mysqlPorts": {}
|
"mysqlPorts": {}
|
||||||
|
|||||||
+27
-16
@@ -161,12 +161,13 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi
|
|||||||
|
|
||||||
const configPath = path.join(configService.getBasePath(), 'generated_configs', 'httpd.conf')
|
const configPath = path.join(configService.getBasePath(), 'generated_configs', 'httpd.conf')
|
||||||
|
|
||||||
// Check if manual edit exists
|
// Check if manual edit exists for global config
|
||||||
|
let skipGlobal = false
|
||||||
if (fs.existsSync(configPath) && !forceProjects) {
|
if (fs.existsSync(configPath) && !forceProjects) {
|
||||||
const content = fs.readFileSync(configPath, 'utf8')
|
const content = fs.readFileSync(configPath, 'utf8')
|
||||||
if (content.includes('# MANUAL_EDIT')) {
|
if (content.includes('# MANUAL_EDIT')) {
|
||||||
console.log('Skipping Apache config generation (Manual Edit detected)')
|
console.log('Skipping Apache global config generation (Manual Edit detected)')
|
||||||
return { binPath, apacheDir, configPath }
|
skipGlobal = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +182,14 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi
|
|||||||
const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`)
|
const projectConfPath = path.join(projectsConfDir, `${p.host}.conf`)
|
||||||
let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath)
|
let shouldGenerate = forceProjects || !fs.existsSync(projectConfPath)
|
||||||
|
|
||||||
|
// If file exists, check if it was manually edited (though we don't have a UI for this yet, good for future)
|
||||||
|
if (!shouldGenerate && fs.existsSync(projectConfPath)) {
|
||||||
|
const currentContent = fs.readFileSync(projectConfPath, 'utf8')
|
||||||
|
if (!currentContent.includes('# MANUAL_EDIT')) {
|
||||||
|
shouldGenerate = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldGenerate) {
|
if (shouldGenerate) {
|
||||||
const phpPort = portMappingService.getPhpPort(p.phpVersion)
|
const phpPort = portMappingService.getPhpPort(p.phpVersion)
|
||||||
let normalizedPath = p.path.replace(/\\/g, '/')
|
let normalizedPath = p.path.replace(/\\/g, '/')
|
||||||
@@ -194,20 +203,22 @@ async function rebuildApacheConfig(forceProjects: boolean = false): Promise<{ bi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectsInclusion = projects.length > 0
|
if (!skipGlobal) {
|
||||||
? `Include "${projectsConfDir.replace(/\\/g, '/')}/*.conf"`
|
const projectsInclusion = projects.length > 0
|
||||||
: ''
|
? `Include "${projectsConfDir.replace(/\\/g, '/')}/*.conf"`
|
||||||
|
: ''
|
||||||
|
|
||||||
await configService.generateConfig('httpd.conf.template', 'httpd.conf', {
|
await configService.generateConfig('httpd.conf.template', 'httpd.conf', {
|
||||||
PORT: settings.apachePort || '8080',
|
PORT: settings.apachePort || '8080',
|
||||||
LISTEN_ADDRESS: settings.allowRemoteAccess ? '0.0.0.0' : '127.0.0.1',
|
LISTEN_ADDRESS: settings.allowRemoteAccess ? '0.0.0.0' : '127.0.0.1',
|
||||||
PHP_PORT: settings.phpPort,
|
PHP_PORT: settings.phpPort,
|
||||||
ROOT: rootPath.replace(/\\/g, '/'),
|
ROOT: rootPath.replace(/\\/g, '/'),
|
||||||
SRVROOT: apacheRoot.replace(/\\/g, '/'),
|
SRVROOT: apacheRoot.replace(/\\/g, '/'),
|
||||||
LOG_DIR: logDir.replace(/\\/g, '/'),
|
LOG_DIR: logDir.replace(/\\/g, '/'),
|
||||||
PHPMYADMIN_DIR: phpMyAdminService.getPath().replace(/\\/g, '/'),
|
PHPMYADMIN_DIR: phpMyAdminService.getPath().replace(/\\/g, '/'),
|
||||||
PROJECTS: projectsInclusion
|
PROJECTS: projectsInclusion
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return { binPath, apacheDir, configPath }
|
return { binPath, apacheDir, configPath }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,8 +259,40 @@ export class PhpManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync(iniPath, finalLines.join('\n'), 'utf8')
|
fs.writeFileSync(iniPath, finalLines.join('\n'), 'utf8')
|
||||||
|
await this.ensureFcgiSettings(version)
|
||||||
return { success: true, message: `Extension ${extName} ${enabled ? 'enabled' : 'disabled'}` }
|
return { success: true, message: `Extension ${extName} ${enabled ? 'enabled' : 'disabled'}` }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async ensureFcgiSettings(version: string): Promise<boolean> {
|
||||||
|
const phpDir = path.join(this.binDir, `php-${version}`)
|
||||||
|
const iniPath = path.join(phpDir, 'php.ini')
|
||||||
|
if (!fs.existsSync(iniPath)) return false
|
||||||
|
|
||||||
|
let content = fs.readFileSync(iniPath, 'utf8')
|
||||||
|
const lines = content.split(/\r?\n/)
|
||||||
|
|
||||||
|
let forceRedirectSet = false
|
||||||
|
let fixPathinfoSet = false
|
||||||
|
|
||||||
|
const newLines = lines.map(line => {
|
||||||
|
const trimmed = line.trim()
|
||||||
|
if (trimmed.startsWith('cgi.force_redirect') || trimmed.startsWith(';cgi.force_redirect')) {
|
||||||
|
forceRedirectSet = true
|
||||||
|
return 'cgi.force_redirect = 0'
|
||||||
|
}
|
||||||
|
if (trimmed.startsWith('cgi.fix_pathinfo') || trimmed.startsWith(';cgi.fix_pathinfo')) {
|
||||||
|
fixPathinfoSet = true
|
||||||
|
return 'cgi.fix_pathinfo = 1'
|
||||||
|
}
|
||||||
|
return line
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!forceRedirectSet) newLines.push('cgi.force_redirect = 0')
|
||||||
|
if (!fixPathinfoSet) newLines.push('cgi.fix_pathinfo = 1')
|
||||||
|
|
||||||
|
fs.writeFileSync(iniPath, newLines.join('\n'), 'utf8')
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const phpManagerService = new PhpManagerService()
|
export const phpManagerService = new PhpManagerService()
|
||||||
|
|||||||
Reference in New Issue
Block a user