nginx + PHP on Windows in 5 minutes
If you’ve ever needed a very fast, stable, no frills, web server to serve up some pages on a home system, then look no further than nginx. The server is rock solid and gets the job done. And the setup and configuration is unmatched in simplicity for other servers of similar capability.
Nginx is native to the UNIX platform, so you’ll need to get a precompiled version or install Cygwin. I opted for the former because there’s already a package available by Kevin Worthington that works very nicely.
Download the stable package and install it. Because of the Cygwin configuration, it will install to c:nginx.
Then download the latest PHP Windows binaries (not the installer) and extract all files to c:nginxphp. We will be using php-cgi.exe because of the nginx fast-cgi capability. Make sure the path is c:nginxphpphp-cgi.exe during the installation.
Almost there…
Go into c:nginxconf and uncomment or modify the following lines in nginx.conf.
location ~ .php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME c:/nginx/html/$fastcgi_script_name;
include fastcgi_params;
}
Then, in the same folder, edit start-nginx.bat to include the following line :
@ECHO OFF
c:\nginxnginx.exe
c:\nginxphpphp-cgi.exe -b 127.0.0.1:9000 -c c:\nginxphpphp.ini
ping 127.0.0.1 -n 1>NUL
echo Starting nginx
echo .
echo .
echo .
ping 127.0.0.1 >NUL
EXIT
Now edit stop-nginx.bat and add the following lines :
@ECHO OFF
taskkill /f /IM nginx.exe
taskkill /f /IM php-cgi.exe
EXIT
It’s not a perfect solution, but works for non-production applications.
That should be it!
If you need to hide that ugly command prompt during startup, just create two files in conf (alongside start-nginx.bat) and enter the following code :
In launch.js :
var objShell = WScript.CreateObject("WScript.Shell");
var result = objShell.Run("cmd.exe /c start-nginx.bat", 0);
// Give some startup time
WScript.Sleep(3000);
// Navigate to homepage
objShell.Run("http://localhost");
In shutdown.js :
var objShell = WScript.CreateObject("WScript.Shell")
var result = objShell.Run("cmd.exe /c stop-nginx.bat", 0)
Now to startup nginx with fast-cgi PHP, just double-click launch.js. To stop, double-click shutdown.js.
You can make yourself a HTML Application to run these JavaScripts and build a basic control panel at a future date.
Update 12/08
Changed the php.ini file location to an absolute path.
Changed the stop-nginx.bat commands to taskkill instead of multiple process -k lines (you can never tell how many instances there may be of php-cgi.exe, so it’s impractical to do it the old way).
Note: Copying entire blocks is recommended as parts of the code is hidden by my display theme. However all the text is there. Hightlighting the whole thing will ensure that no parts are left behind.

Very nice post. I will be linking to you when people email me to ask how to get PHP running with my Nginx for Windows packages. Thanks!
Thanks!
And thank you for creating that package!
I’m trying to build a WordPress site, but I can’t get nginx and PHP (FastCGI) to run. I’ve tried following your instructions but the script hangs on the php-cgi.exe command (and won’t go on to start MySQL which is what I want next!).
Can you give me any suggestion or a location for a log file to look at?
Thanks, John
Hi John.
Unfortunately, I never got to get this past the basic PHP+Nginx combo. MySQL was my next step, but work got in the way.
I hope to have a revised set of steps for this soon.
I am not able to find start-nginx.bat file or other bat file also.
i have installed it to C:\nginx\nginx-0.7.61. How to get those bat file? should we create them.?
Hi Dheeraj.
Once installed, the bat file should be located at : conf\start-nginx.bat Inside your installed folder.
Or if you followed the default steps for the installation, C:\nginx\conf\start-nginx.bat. I recommend installing it to default folders since it’s easier to find where the files are.
In fact, in your start menu, you should see the Nginx folder with links to start and stop the server. Right click on the “Start nginx” link and select “properties”. You should see the path to the file.
But in the instructions, I mention that you should download the “stable” branch of Nginx. Which is 0.6.36 as of this post.
I say to use the stable branch since the development branch may have unforseen issues that could cause problems with the PHP installation.
The steps should be the same for both versions.
I’m with Dheeraj above. Grabbing the precompiled binaries from nginx.net, the .bat files are not included. I dug a little deeper and still couldn’t find the .bat’s in the previous stable releases either. :(
Any ideas here?
Maybe this is it.. Sorry for the clutter.. derived from:
http://www.water3d.com/scripts/php
>> nginx\conf\start-nginx.bat
@ECHO OFF
ECHO Starting PHP FastCGI…
RunHiddenConsole.exe “X:\php\php-cgi.exe” -b 127.0.0.1:9000 -c “X:\php\php5.ini”
echo MySQL is starting with mysql\bin\my.cnf
RunHiddenConsole.exe “X:\mysql\bin\mysqld.exe” –defaults-file=”X:\mysql\bin\my.cnf”
start nginx.exe
ping 127.0.0.1 -n 1>NUL
echo Starting nginx
echo .
echo .
echo .
ping 127.0.0.1 >NUL
EXIT
>> nginx\conf\stop-nginx.bat
@ECHO OFF
ECHO Stopping Nginx…
process -k nginx.exe >nul
process -k nginx.exe
process -k nginx.exe
process -k nginx.exe
ECHO Stopping PHP FastCGI…
process.exe -k php-cgi.exe >nul
ECHO Stopping MySQL…
process -k mysqld.exe >nul
EXIT
Great post! I was hoping not to have to resort to VPC on my windows box. Could it be that your paths are missing slashes or that they have been stripped from above?
Hi Bronius
You’re right! WordPress ate my backslashes! :(
I’m not sure why that happened. It could have been some update made by them. I can’t seem to add them back again.
That modified code you posted looks pretty good actually. I think that’s all you need to control nginx and mysql from the commandline.
I’m glad you found it useful.
i try to run nginx-start.bat but wont start php-cgi. i modify a bit and it works in my station.
and thanks. nice post
Hi Barz
Thanks!
And thanks for sharing!
It might be that WordPress is screwing up the formatting on my code. For some reason, they’ve all been modified since they updated.