When setting up a web server with Nginx and PHP on Windows Server, a common issue is the "No input file specified" error when accessing PHP files, such as http://localhost/info.php
. This error typically indicates that Nginx successfully connects to the PHP FastCGI process, but PHP-CGI cannot locate the requested PHP file. This article outlines a step-by-step guide to diagnose and resolve this issue, based on a real-world scenario involving PHP 8.4.10, Nginx, and nginxWebUI on Windows Server, with the website directory at D:\program\nginx\html
.
Background
The setup includes:
- PHP 8.4.10 (non-thread-safe, installed at
D:\program\php\php-8.4.10-nts-Win32-vs17-x64
). - PHP-CGI running as a service via NSSM, listening on
127.0.0.1:9000
. - Nginx installed at
C:\nginx
, with the website root atD:\program\nginx\html
. - nginxWebUI for managing Nginx configurations.
- Directory permissions set with
IUSR:(RX)
andEveryone:(RX)
usingicacls
. - Initial Nginx configuration issues, including incorrect
root
andfastcgi_param SCRIPT_FILENAME
settings.
The error stemmed from an incorrect fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
and root html;
in the Nginx configuration, causing PHP-CGI to look for files in the wrong path (e.g., /scripts/info.php
instead of D:\program\nginx\html\info.php
).
Step-by-Step Solution
1. Verify PHP-CGI Service
Ensure the PHP-CGI service is running and listening on the correct port.
-
Check Service Status:
Get-Service php-cgi
- Expected output:
Status Name DisplayName ------ ---- ----------- Running php-cgi php-cgi
- If stopped, restart the service:
& "D:\program\nssm\nssm.exe" start php-cgi
- Expected output:
-
Verify Port Listening:
netstat -an | Select-String 9000
- Expected output:
TCP 127.0.0.1:9000 0.0.0.0:0 LISTENING
- If the port is not listening, check for conflicts:
netstat -aon | Select-String 9000 Get-Process -Id <PID>
- Terminate non-PHP-CGI processes:
Stop-Process -Id <PID> -Force
- Terminate non-PHP-CGI processes:
- Expected output:
-
Confirm Single PHP-CGI Process:
Get-Process | Where-Object { $_.Path -like "*php-cgi.exe*" }
- Should show one process at
D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php-cgi.exe
. - If multiple processes exist, stop them:
Stop-Process -Name php-cgi -Force
- Reinstall the NSSM service if needed:
& "D:\program\nssm\nssm.exe" remove php-cgi confirm & "D:\program\nssm\nssm.exe" install php-cgi "D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php-cgi.exe" -b 127.0.0.1:9000 & "D:\program\nssm\nssm.exe" start php-cgi
- Should show one process at
2. Verify Website Directory and Permissions
The website directory (D:\program\nginx\html
) must exist and have appropriate permissions.
-
Check Directory:
Test-Path "D:\program\nginx\html"
- If
False
, create it:New-Item -Path "D:\program\nginx\html" -ItemType Directory
- If
-
Set Permissions:
icacls "D:\program\nginx\html" /grant "IUSR:(RX)" icacls "D:\program\nginx\html" /grant "Everyone:(RX)"
-
Create Test File:
Createinfo.php
inD:\program\nginx\html
:Set-Content -Path "D:\program\nginx\html\info.php" -Value '<?php phpinfo(); ?>'
- Verify file:
Test-Path "D:\program\nginx\html\info.php" Get-Content "D:\program\nginx\html\info.php"
- Set file permissions:
icacls "D:\program\nginx\html\info.php" /grant "IUSR:(RX)"
- Verify file:
3. Fix Nginx Configuration
The No input file specified.
error was caused by incorrect root
and fastcgi_param
settings. Update the Nginx configuration in C:\nginx\conf\nginx.conf
:
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
# Block direct IP access
if ($host ~* "^[0-9.]+$|^[0-9a-f:]+$") {
return 444;
}
root D:/program/nginx/html;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root D:/program/nginx/html;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
-
Key Changes:
- Set
root D:/program/nginx/html;
at theserver
block level to avoid redundancy. - Use
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
to dynamically resolve the file path (e.g.,D:/program/nginx/html/info.php
). - Add
try_files
inlocation /
to handle PHP routing correctly. - Fix
error_page
root
toD:/program/nginx/html
.
- Set
-
Verify
fastcgi_params
:
EnsureC:\nginx\conf\fastcgi_params
exists:Test-Path "C:\nginx\conf\fastcgi_params"
- If
False
, create it:Set-Content -Path "C:\nginx\conf\fastcgi_params" -Value @" fastcgi_param QUERY_STRING \$query_string; fastcgi_param REQUEST_METHOD \$request_method; fastcgi_param CONTENT_TYPE \$content_type; fastcgi_param CONTENT_LENGTH \$content_length; fastcgi_param REQUEST_URI \$request_uri; fastcgi_param DOCUMENT_URI \$document_uri; fastcgi_param SERVER_PROTOCOL \$server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx; fastcgi_param REMOTE_ADDR \$remote_addr; fastcgi_param REMOTE_PORT \$remote_port; fastcgi_param SERVER_ADDR \$server_addr; fastcgi_param SERVER_PORT \$server_port; fastcgi_param SERVER_NAME \$server_name; "@
- If
-
Validate Configuration:
& "C:\nginx\nginx.exe" -t
- Expected output:
nginx: the configuration file C:\nginx\conf\nginx.conf syntax is ok nginx: configuration file C:\nginx\conf\nginx.conf test is successful
- Expected output:
-
Restart Nginx:
& "C:\nginx\nginx.exe" -s reload
4. Update nginxWebUI (if applicable)
If using nginxWebUI:
- Access
http://<server_ip>:8080
. - In the Reverse Proxy or Static Files module, update the
server
block to match the above configuration. - Save and restart Nginx via nginxWebUI.
5. Test PHP
- Access
http://localhost/info.php
in a browser (uselocalhost
due to thereturn 444
rule for IP access). - If the PHP info page appears, the issue is resolved.
- If errors persist:
- No input file specified:
- Confirm
D:\program\nginx\html\info.php
exists. - Check Nginx error logs:
Get-Content "C:\nginx\logs\error.log" -Tail 10
- Test PHP directly:
& "D:\program\php\php-8.4.10-nts-Win32-vs17-x64\php.exe" "D:\program\nginx\html\info.php"
- Confirm
- 403 Forbidden: Re-check permissions:
icacls "D:\program\nginx\html"
- 502 Bad Gateway: Verify PHP-CGI service and port.
- No input file specified:
6. Addressing Linux chown
Context
The user inquired about the Linux command chown -R www:www ./*
, which sets file ownership to the www
user and group. In Windows, this is handled with icacls
. The provided permissions (IUSR:(RX)
and Everyone:(RX)
) are sufficient. For Linux environments (e.g., WSL):
- Check Nginx user:
grep user /etc/nginx/nginx.conf
- Set permissions:
sudo chown -R www-data:www-data /path/to/nginx/html
Conclusion
The No input file specified.
error was resolved by correcting the Nginx configuration:
- Setting
root D:/program/nginx/html;
in theserver
block. - Using
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
to provide the correct file path to PHP-CGI. - Ensuring the PHP-CGI service is running and the website directory has proper permissions.
By following these steps, you can successfully configure Nginx and PHP on Windows Server, enabling dynamic PHP content delivery. Always verify configurations and logs to catch any residual issues.