In the past, whenever I needed a web server on Windows, I would install the XAMPP distribution (comes with Apache, PHP, and MySQL) and call it a day. This time, I wanted to use Nginx instead of Apache as the web server. Below are the steps I took to install Nginx, PHP and MySQL separately on Windows 7.
Install Nginx
Nginx is pretty easy to install on Windows. Just do the following:
- Download the latest Nginx for windows version. (Currently, only 32-bit versions are available.)
- Unzip to a directory like “c:\nginx”.
- Create two subdirectories which “nginx.exe” expects to exist:
mkdir c:\nginx\logs
mkdir c:\nginx\temp - If you want to change the document root from the default “c:\nginx\html” and/or enable directory listing, edit the “c:\nginx\conf\nginx.conf” file and adjust the global “location /” declaration like so:
location / {
#root html; # comment out default root at "nginx_install_dir\html"
root /www; # use new root "c:\www" (assuming nginx is install on c: drive)
index index.html index.htm;
autoindex on; # Add this to enable directory listing
} - To run the Nginx web server, launch the “Command Prompt” and issue these commands:
# Go to Nginx installation directory
c:
cd \nginx
# Start Nginx
start nginx.exeNotes:
- Running “c:\nginx\nginx.exe” without changing to the “c:\nginx” directory will fail because Nginx will look for the log and temp subdirectories, which won’t exist under another directory.
- The “start” command will launch Nginx in a separate window; otherwise, Nginx would take control of the current “Command Prompt” window. That separate window will appear and quickly disappear.
- It is not necessary to run the “Command Prompt” as an administrator.
- Browse to http://localhost/ . You should see a “Welcome to nginx!” page.
- To quit Nginx, in the “Command Prompt” window, do the following:
# Go to Nginx installation directory
c:
cd \nginx
# Quit Nginx
nginx.exe -s quitIf you have started Nginx more than once, the quit command above will only kill the last Nginx process started. To kill all Nginx processes, run the following:
taskkill /F /IM nginx.exe
To avoid launching multiple instances of Nginx, I created the following “intelligent” Nginx start and stop batch script files.
Create a file named “start_nginx.bat” with the content below:
REM Start Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF NOT "%ERRORLEVEL%"=="0" (
REM Nginx is NOT running, so start it
c:
cd \nginx
start nginx.exe
ECHO Nginx started.
) else (
ECHO Nginx is already running.
)
And create a file named “stop_nginx.bat” with this content:
REM Stop Nginx
tasklist /FI "IMAGENAME eq nginx.exe" 2>NUL | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
REM Nginx is currently running, so quit it
c:
cd \nginx
nginx.exe -s quit
ECHO Nginx quit issued.
) else (
ECHO Nginx is not currently running.
)
Install and Configure PHP
To install PHP on Windows:
- Browse to php.net, click on the “Windows downloads” link, and download the latest thread safe version. Either 32-bit or 64-bit versions will work.
- Unzip to a directory, like “c:\nginx\php”.
- Select a PHP configuration (I recommend the development version):
copy c:\nginx\php\php.ini-development c:\nginx\php\php.ini
We will run the “c:\nginx\php\php-cgi.exe” server to allow Nginx to execute PHP scripts using the FastCGI protocol.
- Edit “c:\nginx\conf\nginx.conf” to uncomment the FastCGI section and update the fastcgi_param entries like so:
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}Notes:
- Don’t forget to update the “root” location value if you are not using the default “c:\nginx\html” directory.
- The fastcgi_param values are recommended extra parameters passed to PHP scripts for their optional use.
- Add the following to the bottom of the “start_nginx.bat” file:
REM Start php-cgi
tasklist /FI "IMAGENAME eq php-cgi.exe" 2>NUL | find /I /N "php-cgi.exe">NUL
IF NOT "%ERRORLEVEL%"=="0" (
REM php-cgi is NOT running, so start it
start /min c:\nginx\php\php-cgi.exe -b localhost:9000 -c c:\nginx\php\php.ini
ECHO php-cgi started.
) else (
ECHO php-cgi is already running.
)Notes:
- Use localhost instead of 127.0.0.1 to support both IPv4 and IPv6 addressing (if it is enabled). 127.0.0.1 was not resolvable on my IPv6-enabled Windows installation. (Strangely, using 127.0.0.1 in the nginx.conf’s FastCGI section above is okay though.)
- Unfortunately, “start php-cgi.exe” will show a separate “Command Prompt” window which will remain visible; the “/min” parameter flag is used to minimize that window. If you really want to prevent that window from appearing, you’ll need to use a VBScript to execute the batch file.
- The order in which Nginx and php-cgi are launched does not matter.
- The PHP distribution has a “php-win.exe” file which supposedly is the same as “php-cgi.exe” but without throwing up a “Command Prompt” window; however, I could not get “php-win.exe” to run as a server.
- Add the following to the bottom of the “stop_nginx.bat” file:
REM Stop php-cgi
tasklist /FI "IMAGENAME eq php-cgi.exe" 2>NUL | find /I /N "php-cgi.exe">NUL
IF "%ERRORLEVEL%"=="0" (
REM php-cgi is currently running, so quit it
taskkill /f /IM php-cgi.exe
ECHO php-cgi killed.
) else (
ECHO php-cgi is not currently running.
) - Create a PHP test script at “c:\nginx\html\info.php”with the following content:
<?php
phpinfo();
?> - Run “start_nginx.bat” to launch Nginx and php-cgi. Browse to http://localhost/info.php and you should see information about the PHP installation.
Install MySQL
Let’s get MySQL up and running:
- Download the latest MySQL Community Server. I suggest the “ZIP Archive” distributions, either the 32-bit or 64-bit version. Click the Download button. You don’t need to log in to download, just click the “No thanks, just start my download” link at the bottom of the page.
- Unzip to a directory like “c:\nginx\mysql”.
- Select the default MySQL configuration:
copy c:\nginx\mysql\my-default.ini c:\nginx\mysql\my.ini
- Initialize MySQL by running the “Command Prompt” as an administrator (so Windows registry keys and service can be created) and these commands:
# Current directory must be the MySQL installation directory
cd c:\nginx\mysql
# Initialize database with root user and blank password
bin\mysqld --initialize-insecure
# Install MySQL as a Windows service
bin\mysqld --install-manual
# Start MySQL Server service
net start mysql - Test by running these commands (administrator privileges not required):
# Run MySQL client, skipping password input since blank
c:\nginx\mysql\bin\mysql.exe -u root --skip-password
# Run some commands and a query
mysql> SHOW databases;
mysql> USE mysql;
mysql> SHOW tables;
mysql> DESC user;
mysql> SELECT * FROM user;
# Assign new root password
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
# Quit MySQL client
mysql> quit;
# Run MySQL client with password prompt
c:\nginx\mysql\bin\mysql.exe -u root -p
# Input the new_password - Enable PHP mysqli extension by uncommenting the line below in “c:\nginx\php\php.ini”:
extension=php_mysqli.dll
- Create a test script named mysql.php with the following content:
<?php
// HTML response header
header('Content-type: text/plain');
// Database connection parameters
$DB_HOST = 'localhost';
$DB_PORT = 3306; // 3306 is default MySQL port
$DB_USER = 'root';
$DB_PASS = ''; // blank or new_password
$DB_NAME = 'mysql'; // database instance name
// Open connection (all args can be optional or NULL!)
$mysqli = new mysqli($DB_HOST, $DB_USER, $DB_PASS, $DB_NAME, $DB_PORT);
if ($mysqli->connect_error) {
echo 'Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error . PHP_EOL;
} else {
// Query users
if ($result = $mysqli->query('SELECT User FROM user')) {
echo 'Database users are:' . PHP_EOL;
for ($i = 0; $i < $result->num_rows; $i++) {
$result->data_seek($i);
$row = $result->fetch_assoc();
echo $row['User'] . PHP_EOL;
}
$result->close();
} else {
echo 'Query failed' . PHP_EOL;
}
}
// Close connection
$mysqli->close();
?> - Run “stop_nginx.bat” followed by “start_nginx.bat” to restart Nginx and php-cgi processes. Browse to http://localhost/mysql.php and you should see a listing of the MySQL database users.
- You can stop and/or uninstall the MySQL Server service by running “Command Prompt” as an administrator and issuing these commands:
# Stop MySQL Server service
net stop mysql
# Uninstall MySQL Server service
sc delete mysql
You don’t have to run MySQL Server as a Windows service. Instead, you can run MySQL Server from the “Command Prompt” (administrator privileges not required) like so:
c:\nginx\mysql\bin\mysqld.exe
# Stop MySQL Server
c:\nginx\mysql\bin\mysqladmin.exe -u root shutdown
Unfortunately, the “mysqld.exe” will take control of the “Command Prompt” window and the “start” command does not work in this case, so you will need to open a second “Command Prompt” window in order to issue the shutdown command.
Some info taken from:
Thanks very much for your article.
It’s work for me ^_^
My OS is Win8.1 64bit. Followed your instructions, when I typed localhost in Chrome, the page returned “This site can’t be reached. localhost refused to connect”. I use AVG antivirus. I turn off AVG and tried to access localhost again. Same error message.
Also, when I looked at the taskmanager, there were 2 nginx.exe (32 bit) windows processes when I issued “start nginx” command in the nginx folder. I deleted one of them and tried to access localhost page. Same error message.
What should be done to correct this error and get localhost to display the “Welcome to nginx!” page?
Thanks in advance.
Hi,
Sorry for the delayed reply. It looks like you are at step 6 “Browse to http://localhost/“. I just tried the latest nginx-1.11.4 build on my Windows 10 64-bit system and it worked as expected.
I can think of three issues that could be causing the problem you are seeing. Could you try the following?
You can also check the log file at “c:\nginx\logs\error.log” to see if there are error messages that might indicate what the problem is.
Hope that helps.
Chanh
Chanh, followed your instructions; worked first time “out of the gate” (on Windows 10 x64.) Thank you!
Thanks very much. Your explanation was concise and very useful. I just started using ngnix and this saved me a lot of time.
It cannot load any extension (module) because the path is incorrect. I had to edit php.ini and change to:
The tutorial was very helpful, thank you!
Thank you. I wanted to use my existing MariaDB installation and all I had to do is skip parts of the “Install MySQL” section of your post.
I was wondering if there would be any problems with using the installed version (and not the zip version), but everything worked like a charm. 🙂
Great tutorial, helped me a lot, thanks!
Why work this hard when you can install a php development stack based on nginx?
https://sourceforge.net/projects/wtnmp/
WinNMP – Windows Nginx MySql Php stack
A lightweight, fast and stable server stack for developing php mysql applications on windows, based on the excellent webserver Nginx. A lighter alternative to XAMPP and WAMP, with Composer, Adminer, LetsEncrypt certificates, WinSCP, multiple PHP versions, projects and virtual servers.
Thanks for letting us know about WinNMP, Spa. It does look more lightweight than XAMPP/WAMP, though it includes MariaDB (a fork of MySQL, instead of MySQL) and numerous other utilities (Redis, WinSCP, etc.) which some may not need or want.
Thank you very much for your helpful tutorial! It worked great for me with two minor changes:
– I had to uncomment the line ‘extension_dir = “ext”‘ in php.ini
– The test script mysql.php doesn’t work for the user ‘root’. I had to create a new user
Thanks, Wolfgang, for letting us know. Looks like Konstantinos earlier had a related issue with the ‘extension_dir’ directive also.
localhost/mysql.php doesn’t work “no input included” os something like this
have any tips what could go wrong?
where I should include this file mysql.php?
According to this stackoverflow page, NGINX – No input file specified. – php Fast/CGI, the problem is likely the FastCGI configuration.
Try the following, according to the page:
mysql configuration is not working for Windows (x86, 64-bit), ZIP Archive file. php ini file is missing from mentioned path