How to Install Nginx, PHP, and MySQL on Windows 11

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

  1. Nginx
  2. PHP
  3. MySQL
    1. Using Installer
    2. Using Zipped
  4. Add them to PATH environment
  5. Wrap Up

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
    Posted March 31, 2020 4:40 pm 0Likes

    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
      Posted May 27, 2020 1:02 am 0Likes

      you need to run the script in powershell, not in cmd

  • Daniel Enyi
    Posted April 26, 2020 9:37 pm 0Likes

    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
    Posted April 26, 2020 10:27 pm 0Likes

    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
      Posted April 27, 2020 3:50 am 0Likes

      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
    Posted April 27, 2020 3:02 pm 0Likes

    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
    Posted April 29, 2020 6:26 am 0Likes

    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
    Posted May 4, 2020 8:07 am 0Likes

    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
      Posted May 27, 2020 1:02 am 0Likes

      You need to run the script in powershell, not in cmd

      • MALLIKARJUN S
        Posted November 13, 2021 3:09 pm 0Likes

        Thank you for the information. But I am also facing the same problem as mention. I am running in PowerShell itself.

  • Carlos
    Posted May 27, 2020 12:36 am 0Likes

    Rino, Marie, you need to run the script en powershell, not in cmd

  • Mohamed Kamal
    Posted January 9, 2021 1:12 pm 0Likes

    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
      Posted January 15, 2021 1:48 am 0Likes

      Thank you for this great fix Mohamed, will add this to the article.

  • Geebee
    Posted January 22, 2021 7:08 pm 0Likes

    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
      Posted January 23, 2021 6:34 am 0Likes

      Hi Geebee, have you add it to the PATH environment?

      • Geebee
        Posted January 23, 2021 1:01 pm 0Likes

        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
    Posted January 23, 2021 12:39 pm 0Likes

    Yes.

  • Patrik
    Posted February 4, 2021 7:40 pm 0Likes

    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
      Posted March 7, 2021 9:16 am 0Likes

      Same here 🙁

      • CodeFAQ
        Posted March 7, 2021 9:28 am 0Likes

        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
          Posted March 7, 2021 10:03 am 0Likes

          Unfortunately stile the same “‘QUERY’ is not recognized as an internal or external command,
          operable program or batch file.”

          • Bat
            Posted May 5, 2021 1:19 pm 0Likes

            Hi, thank you very much for this work!
            I have the same problem with QPROCESS on windows 10 .. Did you find a solution?

  • AgustD
    Posted March 23, 2021 3:09 pm 0Likes

    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
    Posted December 9, 2021 11:24 am 0Likes

    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
      Posted July 4, 2023 2:22 pm 0Likes

      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
    Posted January 25, 2023 3:27 pm 0Likes

    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;
    }

Leave a Reply to FelipeBHZ Cancel reply

trabzon escort yalova escort Samsun escort izmit escort nazilli escort