Installing a web server using a distribution package like XAMPP, and WinNMP are probably the easiest solution to make your localhost server works. But what if we wanted to make it from scratch? and avoid duplication whenever we install a composer, laravel and other development kit. Also, you’re free to upgrade them whenever a new version comes out.
The guide has been updated to run on the latest Windows 11, it should work on Windows 10, 8 and 7.
Table of Contents
If you’re not running the latest Windows 11, you need to install the version of VC_Redist you can get it from at https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0, then look for Visual Studio 2015, 2017 and 2019, then download your either vc_redist.x86.exe or vc_redist.x64.exe. If you don’t have that, you’ll get this error message when using the PHP.
The code execution cannot proceed because VCRUNTIME140.dll was not found. Reinstalling the program may fix this problem.
or if you have a lower version of VC_Redist installed, you’ll get this error.
'vcruntime140.dll' 14.0 is not compatible with this PHP build linked with 14.16 in Unknown on line 0 - Google Search
That’s for installing the prerequisite. Let’s now install the latest version of NGINX 1.19.6 + PHP 8.0+ MySQL 8.0.22.
Nginx
To install nginx, you need to download it from http://nginx.org/en/download.html. Select the Mainline version zip files. Currently, it’s nginx/Windows-1.19.6.
Once downloaded, create a folder in your computer. You may follow our naming convention or create your own. In our case we create a folder at C:\WebServer
.
After created a folder, create again a folder for our Nginx. It should be C:\WebServer\nginx
.
Unzip the downloaded nginx-1.19.6.zip at C:\WebServer\nginx
folder.
It’s all good for now, we can discuss later how we activate it.
PHP
To get binaries installation for PHP on Windows, you can grab it at https://windows.php.net/download/.
Then at the PHP 8.0, download the VS16 x64 Non Thread Safe zip file, so we can use it alongside with our Nginx and MySQL.
If you want to use the older version, PHP 7.4, download the VC15 x64 Non Thread Safe zip file.
Once downloaded, create a folder C:\WebServer\php
and extract the file at C:\WebServer\php
MySQL
There are two ways to install MySQL by its installer or via zip. Both has pros and cons. Installing using its installer is easier and will not allow you to set things. Advantage of using the zipped version is its portability, you can easily transfer everything in a new computer.
Using Installer
To install MySql, you can downloaded the installer version at https://dev.mysql.com/downloads/installer/. Pick the mysql-installer-web-community-8.0.23.0.msi.
Run the installation, and when you are asked to what to install. Just install MySQL Server, other module is not needed.
You’ll then asked to set your MySQL password. Just fill up the form and when finish, the MySQL will run automatically.
We also suggest to start MySQL when windows start.
Using Zipped
You can download the zipped version at https://dev.mysql.com/downloads/mysql/. Scroll down and look for Windows (x86, 32 & 64-bit), ZIP Archive.
Once done, create a folder and unzipped the downloaded file at C:/WebServer/mysql
.
Launch a command prompt as a Administrator and we can now initialize the MySQL setup.
cd C:/WebServer/mysql/bin
mysqld --initialize-insecure
You can then run the mysql using this command. Make sure to Allow Access when it asked for permission.
cd C:/WebServer/mysql/bin
mysqld --console
You need to open a new command prompt window to login to our MySQL. (Do not close the previous command prompt or else you’ll get an error saying ‘error 2003 (HYOO): Can’t connect to MySQL server on ‘localhost’ (10061))
cd C:/WebServer/mysql/bin
mysql -u root
In MySQL 8.0 and above, the default authentication plugin is caching_sha2_password which not allow you to connect to the mysql using the default native login in php. Most users will get this error message saying “Connection failed: The server requested authentication method unknown to the client”. To enable it back to native, we have to set your root password with mysql_native_password.
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '';
FLUSH PRIVILEGES;
Add them to PATH environment
In order for us to call nginx, php and MySQL straight from the command line or Windows Powershell without going to its directory, this is needed for other module like Laravel and Composer. We need to add it in the PATH directory.
In the Search bar (Cortana) in your Windows taskbar, just search Edit the system environment variables.
At the bottom, Click the Environment Variables.
Then, you can either add both on User Variables for YOUR_USERNAME or System variables path. Look for Path then click Edit.
Now, we have to add these directories. If you use the installer for MySQL, no need to add the C:\WebServer\mysql\bin
.
C:\WebServer\nginx
C:\WebServer\php
C:\WebServer\mysql\bin
Once done, click OK.
To see if it works, try running these commands using the Windows Powershell or Command Prompt.
php -v
mysqld -V
nginx -v
You should get these output.
PHP 8.0.1 (cli) (built: Jan 5 2021 23:43:33) ( NTS Visual C++ 2019 x64 )
Copyright (c) The PHP Group
Zend Engine v4.0.1, Copyright (c) Zend Technologies
Ver 8.0.22 for Win64 on x86_64 (MySQL Community Server - GPL)
nginx version: nginx/1.19.6
You cannot call yet the nginx -t
at the command prompt, because this will cause an error which are looking for files on its relative directory. We can discuss this later on how to get rid of this using a batch command file.
nginx: [alert] could not open error log file: CreateFile() "logs/error.log" failed (3: The system cannot find the path specified)
2020/02/27 11:43:49 [emerg] 400#7148: CreateFile() "C:\WebServer/conf/nginx.conf" failed (3: The system cannot find the path specified)
nginx: configuration file C:\WebServer/conf/nginx.conf test failed
Wrap up
Now that we already added them to path. Let’s do some finishing touch.
To make PHP communicate with our MySQL. At C:\WebServer\php
, we need to add the module in our PHP. First, rename the php.ini-production to php.ini file
After renaming it, open the php.ini file, search for extension=/path/to/extension/mysqli.so and uncomment the line by removing the semi-colon “;”, then change its value to our mysqli dll (Unfortunately, we need to manually add the exact path of the dll because it is causing error when just using the default extension name).
; When the extension library to load is not located in the default extension
; directory, You may specify an absolute path to the library file:
;
extension=C:\WebServer\php\ext\php_mysqli.dll
You can then also enable other module extension (DLLs) that are needed for your program. Like the following that are needed for WordPress.
extension=C:\WebServer\php\ext\php_curl.dll
extension=C:\WebServer\php\ext\php_pdo_mysql.dll
extension=C:\WebServer\php\ext\php_mbstring.dll
extension=C:\WebServer\php\ext\php_gd.dll
extension=C:\WebServer\php\ext\hp_soap.dll
We also need to edit our loadable extensions module to avoid PHP Warning for our MySQL. Search and find the ;extension_dir = "ext"
then uncomment and replace the value with extension_dir = "c:\WebServer\php\ext\"
. (Credits to Mohamed for this tip)
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir = "c:\WebServer\php\ext\"
In the next step, we will be making a batch file. But there is a problem, running nginx and php-cgi in the batch command line will not allow us to execute the next line of code. Simply because the program is not yet closed for it to proceed on to the next line.
In order for us to run each lines of code of our batch file, we need to hide the command prompt windows by using RunHiddenConsole, you can download this at their official website (https://redmine.lighttpd.net/attachments/660/RunHiddenConsole.zip).
At C:\WebServer\nginx
, unzip the RunHiddenConsole.zip.
Then still at C:\WebServer\nginx
, we need to create a batch file called C:\WebServer\nginx\myserver.bat
. This is where we will start and stop our nginx and php-cgi by using a single command line. Add the following code. (Thank you to Mohamed for enhancing this code).
@echo off
cd C:\WebServer\nginx
IF "%1" == "stop" (
GOTO STOPSERVER
)else IF "%1" == "start" (
GOTO STARTSERVER
)else (
echo Use these commands:
echo.
echo myserver start
echo myserver stop
)
GOTO END
:STARTSERVER
QPROCESS * | find /I /N "mysqld.exe">NUL
IF "%ERRORLEVEL%"=="0" (
echo MYSQLD is already running.
)else (
RunHiddenConsole.exe mysqld --console
echo MYSQLD is now running.
)
QPROCESS * | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
echo NGINX is already running.
)else (
RunHiddenConsole.exe nginx
echo NGINX is now running.
)
QPROCESS * | find /I /N "php-cgi.exe">NUL
IF "%ERRORLEVEL%"=="0" (
echo PHP-CGI is already running.
)else (
RunHiddenConsole.exe php-cgi -b 127.0.0.1:9000
echo PHP-CGI is now running.
)
echo.
echo To stop, type "myserver stop"
GOTO END
:STOPSERVER
QPROCESS * | find /I /N "mysqld.exe">NUL
IF "%ERRORLEVEL%"=="0" (
taskkill /F /IM mysqld.exe>NUL
echo MYSQLD ended successfully.
)else (
echo MYSQLD is not running
)
QPROCESS * | find /I /N "nginx.exe">NUL
IF "%ERRORLEVEL%"=="0" (
::nginx -s stop
taskkill /F /IM nginx.exe>NUL
echo NGINX ended successfully.
)else (
echo NGINX is not running
)
QPROCESS * | find /I /N "php-cgi.exe">NUL
IF "%ERRORLEVEL%"=="0" (
taskkill /F /IM php-cgi.exe>NUL
echo PHP-CGI ended successfully.
)else (
echo PHP-CGI is not running
)
:END
After that, you can now use these commands for starting and stopping your server at the Command Prompt.
- myserver start – It will start Nginx, and PHP
- myserver stop – It will stop all instances of Nginx and PHP
But before running the commandline above, we have to edit some blocks on our C:/WebServer/nginx/conf/nginx.conf
.
First we have to make sure index.php is been recognized by our nginx. find the location / {} block and change it with the following:
location / {
root html;
index index.php index.html index.htm;
}
Next is we have to make sure nginx know where to run the php files. Find and uncomment the block that says location ~ .php$ {}, the one that says “pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000”. Change it with the following:
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Once everything is good. Create a file in C:\WebServer\nginx\html\testing.php
. Then write this sample PHP codes with MySQL connection checker (Make sure to fill up your MySQL login, the default username is root).
<?php
echo "PHP works!<br/><br/>";
$servername = "localhost";
$username = "root";
$password = "";
// Create connection
$conn = mysqli_connect($servername, $username, $password);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
echo "Connected to MYSQL successfully";
?>
Then at the command prompt. Let’s start our server. (Do not forget to Allow Access when Windows Defender Firewall is asking for permission.)
myserver start
You should get example output below.
MYSQLD is now running.
NGINX is now running.
PHP-CGI is now running.
To stop, type "myserver stop"
Now to really check its indeed running. Check at your browser and access https://localhost/testing.php.
PHP works!
Connected to MYSQL successfully
26 Comments
Marie
Hello, thanks for this amazing tuto, but i’ve this error :
“‘QPROCESS’ n’est pas reconnu en tant que commande interne
ou externe, un programme exécutable ou un fichier de commandes.”
Any idea ?
Thx A LOT 🙂
carlos
you need to run the script in powershell, not in cmd
Daniel Enyi
Thanks for the powerful write up. But my question is can I change the default username and password to a personal one? Or is it the same thing as xampp and others?
Daniel Enyi
Can I use it in real time production hosting business websites with full confidence. Are my files safe or are they vulnerable? Please, help.
CodeFAQ
Hi Daniel, yes it is same as what other cloud hosting are using.. you can change the username and password in the article..
Daniel Enyi
Thank you so much for your response. But What I really want to find out is the security conditions. Can I use it to host websites in real business world for myself and my clients without much fear of vulnerability?
Thomas Raddatz
Great tutorial. Thank you so much for that! Here are a few things I had to fix to make it working for me:
1) Changed php.ini: extension_dir = “c:\WebServer\php\ext\”
Error: PHP Warning: PHP Startup: Unable to load dynamic library ‘mysqli’ (tried: C:\php\ext\mysqli (Das angegebene Modul wurde nicht gefunden.), C:\php\ext\php_mysqli.dll (Das angegebene Modul wurde nicht gefunden.)) in Unknown on line 0
2) Fixed copy & paste (must be back slashes) for this given path: “C:/WebServer/nginx/conf/nginx.conf”
3) I downloaded the VC_Redist from here “https://support.microsoft.com/de-de/help/2977003/the-latest-supported-visual-c-downloads”. There is no need for installing Visual Studio.
Last but not least I added the following lines to myserver.bat to keep the current directory:
1) Inserted after @echo off: SET SCRIPT_HOME=%~dp0
2) Added at the end of the script: cd %SCRIPT_HOME%
rino
hello,
thanks for the tutorial, i have question about this part
At C:\WebServer\nginx, unzip the RunHiddenConsole.zip.
Then still C:\WebServer\nginx, we need to create a batch file called C:\WebServer\nginx\myserver.bat.
i already make the file but when i run the myserver start is have error like this
‘QPROCESS’ is not recognized as an internal or external command,
operable program or batch file.
please help.
carlos
You need to run the script in powershell, not in cmd
MALLIKARJUN S
Thank you for the information. But I am also facing the same problem as mention. I am running in PowerShell itself.
Carlos
Rino, Marie, you need to run the script en powershell, not in cmd
Mohamed Kamal
In order to make this work full normally, some more few steps needed:
1) Under location block: find the line “index index.html index.htm” and add ” index.php” to the end of it.
This will fix the problem of getting 403 error while accessing some location with index.php in them as the default page.
Plus the steps mentioned by @Thomas Raddatz in an above comment (I excerpted what I just needed):
2) In php.ini: change:
extension_dir = “./”
to:
extension_dir = “c:\WebServer\php\ext\”
This will fix the problem of getting a warning like this:
Error: PHP Warning: PHP Startup: Unable to load dynamic library ‘mysqli’ (tried: C:\php\ext\mysqli (Das angegebene Modul wurde nicht gefunden.), C:\php\ext\php_mysqli.dll (Das angegebene Modul wurde nicht gefunden.)) in Unknown on line 0
3) Added the following lines to myserver.bat to keep the current directory:
1) Inserted after @echo off: SET SCRIPT_HOME=%~dp0
2) Added at the end of the script: cd %SCRIPT_HOME%
CodeFAQ
Thank you for this great fix Mohamed, will add this to the article.
Geebee
Thank you for great tutorial.
1) When I run “mysqld -v” in powershell or cmd, it just freezes there, doesn’t return anything.
2) And myserver start – ‘myserver’ is not recognized
CodeFAQ
Hi Geebee, have you add it to the PATH environment?
Geebee
Actually to be more precise, I successfully run php -v, and nginx -v and get the proper message. When I run mysqld -v, it just returns to the prompt with no message.
I have all the PATH variables set.
Still it does not recognize ‘myserver’ … ‘myserver’ is not recognized as an internal or external command,
operable program or batch file.
Geebee
Yes.
Patrik
Hello, I also have message ‘QPROCESS’ is not recognized as an internal or external command,
operable program or batch file. No matter if I use powershell or cmd still same message.
Mariusz
Same here 🙁
CodeFAQ
Hi Mariusz, I am sorry for that, it seems “QPROCESS” is only available to the latest version of Windows 10. Can you try “QUERY PROCESS” instead? just replace the QPROCESS code in the bat file.
mARIUSZ
Unfortunately stile the same “‘QUERY’ is not recognized as an internal or external command,
operable program or batch file.”
Bat
Hi, thank you very much for this work!
I have the same problem with QPROCESS on windows 10 .. Did you find a solution?
AgustD
when I turn it off appears
ERROR: The process “mysqld.exe” with PID 11972 could not be terminated.
Reason: Access is denied.
ERROR: The process “mysqld.exe” with PID 9732 could not be terminated.
Reason: Access is denied.
help me
Ghanshyam
https://prnt.sc/22g750c
after restart server
This site can’t be reachedlocalhost refused to connect.
Try:
Checking the connection
Checking the proxy and the firewall
ERR_CONNECTION_REFUSED
I am getting this issue
Yand
Hi guys! Thank you so much for this amazing work.
Just to contribute also. In case you experienced the same problem as I did.
1- Launching “https://localhost/testing.php”, doesn’t work but when I just tap “localhost/testing.php” or “http://localhost/testing.php”, it work. I guess there is a supplementary configuration before having https.
2. There is this error : “RunHiddenConsole.exe” not an internal command ……
So solve I just added “C:\WebServer\nginx\RunHiddenConsole” to path.
Regards.
FelipeBHZ
Excellent guide! 🙂
I was fed up with mamp, wamp, laragon and other local dev stuff.
I could make it work on Windows 11 with nginx, php74 and mysql 8.0
The only thing I had to add is this line
include fastcgi.conf;
right after the last ‘include’ in the FastCGI block.
The final block is like this:
# 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;
include fastcgi_params;
include fastcgi.conf;
}