Wordpress for Windows Server - Wed, Apr 7, 2021
How to setup wordpress in Windows Server - 2019
I have recently came across an issue while migrating a website to an on-prem server. The server had Windows server 2019 standard and need to have Wordpress + MySql + PHP intalled. Usually it is easy to setup a Wordpress server with the Internet Information Services(IIS) + Windows Platform Installer(WPI). The setup seems to be very straightforward and you can follow up this simple guide here. The guide is for 2016 but it should work for newer version as well.
I found out that the WPI does not work properly with the latest version of IIS (v10+), only until version 8 express. I even tried to install all the windows features using this simple method:
- Download this file Roles.csv
- Run PowerShell / CMD in adminstrator mode
- Run the command from the same folder.
Import-Csv Roles.csv | foreach{Add-WindowsFeature $_.name }
- Then run the IIS + WPI setup to install Wordpress.
But the setup still failed for me. Seems to be the WPI direct links are outdated and have not been updated for the newer version of Windows.
So I took another approach to this. According to Wordpress, to run the application in a server they recommend the host supports:
- PHP version 7.4 or greater.
- MySQL version 5.6 or greater OR MariaDB version 10.1 or greater.
- HTTPS support That’s really it. They also recommend Apache or Nginx as the most robust and featureful server for running WordPress, but any server that supports PHP and MySQL will do.
I have decided to share my experience with this setup which worked for me at the end. Your setup might differ, but the basic idea would be the same. I might add a script at the end of the guide in the future.
Step by step guide to install Wordpress on a Windows Server 2016 and above
The instructions use Windows PowerShell, and are also suitable for servers with and without the Desktop UI feature installed (Server Core). These instructions can be also used with Windows 10!
We are going to install the following components:
- Internet Information Services (IIS)
- URL Rewrite
- File System Security PowerShell Module
- PHP
- Visual C++ Redistributables
- MySQL Server
- WinCache
- PHP Manager for IIS
- WordPress
Pre-requisites
We need configure some small components before go forward with the setup.
- Run PowerShell / CMD in adminstrator mode
- Change into any directory/folder of your choice, I used Downloads folder:
cd ~\Downloads
- Set the Security Protocol Type for HTTPS downloads to TLS 1.2:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
IIS:
- Install IIS and Windows features:
Install-WindowsFeature Web-Server,Web-Common-Http,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-App-Dev,Web-CGI,Web-Health,Web-Http-Logging,Web-Log-Libraries,Web-Request-Monitor,Web-Security,Web-Filtering,Web-Performance,Web-Stat-Compression,Web-Mgmt-Tools,Web-Mgmt-Service,WAS,WAS-Process-Model,WAS-NET-Environment,WAS-Config-APIs,Net-Framework-Core -IncludeManagementTools
- for Win 10 you need to run this:
Enable-WindowsOptionalFeature -FeatureName IIS-WebServerRole,IIS-WebServer,IIS-CommonHttpFeatures,IIS-StaticContent,IIS-DefaultDocument,IIS-DirectoryBrowsing,IIS-HttpErrors,IIS-ApplicationDevelopment,IIS-CGI,IIS-HealthAndDiagnostics,IIS-HttpLogging,IIS-LoggingLibraries,IIS-RequestMonitor,IIS-Security,IIS-RequestFiltering,IIS-Performance,IIS-HttpCompressionStatic,IIS-WebServerManagementTools,IIS-ManagementConsole,IIS-ManagementService,WAS-WindowsActivationService,WAS-ProcessModel,WAS-NetFxEnvironment,WAS-ConfigurationAPI,NetFx3 -Online -All -Source D:\Sources\sxs
- Enable the Remote Management Service:
Set-ItemProperty HKLM:\SOFTWARE\Microsoft\WebManagement\Server EnableRemoteManagement 1 Set-Service WMSVC -StartupType Automatic Start-Service WMSVC
URL-rewrite:
- Download URL Rewrite 2.1 extension for IIS, which enables Permalinks functionality in WordPress:
Invoke-WebRequest "http://download.microsoft.com/download/D/D/E/DDE57C26-C62C-4C59-A1BB-31D58B36ADA2/rewrite_amd64_en-US.msi" -OutFile "rewrite_amd64.msi"
- and install it:
Start-Process "msiexec.exe" "/i rewrite_amd64.msi /qn" -Wait
FS security:
- Download File System Security PowerShell Module which adds a number of cmdlets to manage file system permissions not currently present in PowerShell.
Invoke-WebRequest "http://download.microsoft.com/download/D/D/E/DDE57C26-C62C-4C59-A1BB-31D58B36ADA2/rewrite_amd64_en-US.msi" -OutFile "rewrite_amd64.msi"
- and install it:
Start-Process "msiexec.exe" "/i rewrite_amd64.msi /qn" -Wait
- Set the PowerShell script execution policy to allow downloaded scripts to be run as long as they have been signed by a trusted publisher:
Set-ExecutionPolicy RemoteSigned CurrentUser
PHP
- We need install these three main components:
- PHP
- PHP Manager for IIS – used to register and configure PHP with IIS
- Windows Cache Extension for PHP – installed to boost PHP performance.
- Install latest version of PHP release from here and WinCache from here. I would use any of the latest with Win32-vs[XX]-x[XX].zip at the end for PHP. In this guide I chose php-8.0.3-Win32-vs16-x86.zip for PHP and wincache-2.0.0.2-7.0-nts-vc14-x64.exe for WinCache
$PHP_ZIP = "php-8.0.3-Win32-vs16-x86.zip.zip" $PHP_PATH = "$env:ProgramFiles\PHP\v8.0" $PHP_DATA = "$env:ProgramData\PHP\v8.0"
- Download the PHP:
cd ~\Downloads Invoke-WebRequest "http://windows.php.net/downloads/releases/$PHP_ZIP" -OutFile "$PHP_ZIP"
- and unzip it:
Expand-Archive "$PHP_ZIP" "$PHP_PATH"
- and copy over to C:\ProgramFiles directory:
Copy-Item "$PHP_PATH\php.ini-production" "$PHP_PATH\php.ini"
WinCache:
- Download WinCache:
$WINCACHE = "wincache-2.0.0.2-7.0-nts-vc14-x64.exe" Invoke-WebRequest "https://nchc.dl.sourceforge.net/project/wincache/development/$WINCACHE.exe" -OutFile "$WINCACHE.exe"
- and install it:
Start-Process "$WINCACHE.exe" "/Q /C /T:""$env:USERPROFILE\Downloads\$WINCACHE""" -Wait
- and copy it to the C:\ProgramFiles\ext\ directory:
Copy-Item "$WINCACHE\php_wincache.dll" "$PHP_PATH\ext\php_wincache.dll"
- and finally remove it
Remove-Item "$WINCACHE" -Recurse -Force
PHP Manager:
- Now download PHP manager for IIS:
Invoke-WebRequest "http://www.technologist.site/wp-content/uploads/0000/PHPManagerForIIS-1.4.0-x64.msi" -OutFile "PHPManagerForIIS-1.4.0-x64.msi"
- and install it
Start-Process "msiexec.exe" "/i PHPManagerForIIS-1.4.0-x64.msi /qn" -Wait
- Add PHP Manager PowerShell Snap-In:
Add-PsSnapin PHPManagerSnapin
- Register PHP with IIS:
New-PHPVersion "$PHP_PATH\php-cgi.exe"
- Configure PHP extensions and settings:
Set-PHPExtension php_wincache.dll Enabled Set-PHPExtension php_mysql.dll Disabled Set-PHPSetting date.timezone UTC Set-PHPSetting upload_max_filesize 20M
- Relocate the PHP “Logs” and “Upload” directory:
$PHP_LOGS = "$PHP_DATA\Logs" New-Item $PHP_LOGS -ItemType Directory | Out-Null Set-PHPSetting error_log "$PHP_LOGS\php_errors.log" $PHP_UPLOAD = "$PHP_DATA\Upload" New-Item $PHP_UPLOAD -ItemType Directory | Out-Null Add-NTFSAccess $PHP_UPLOAD IUSR Modify Add-NTFSAccess $PHP_UPLOAD IIS_IUSRS Modify Set-PHPSetting upload_tmp_dir "$PHP_UPLOAD"
PHP is now done setup
Visual C++:
- Download Microsoft Visual C++ 2013 Redistributable package:
Invoke-WebRequest "https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe" -OutFile "vc_redist_2013_x64.exe"
- install it:
.\vc_redist_2013_x64.exe /Q
MYSQL
- Install MySQL 5.7 installation (find the latest version from this list here). In this guide we are using mysql-8.0.22-winx64.zip:
$MYSQL_ZIP = "mysql-8.0.22-winx64" $MYSQL_URL = "https://dev.mysql.com/get/Downloads/MySQL-5.7/$MYSQL_ZIP.zip" $MYSQL_NAME = "MySQL" $MYSQL_PROD = "$MYSQL_NAME Server 8.0" $MYSQL_PATH = "$env:ProgramFiles\$MYSQL_NAME" $MYSQL_BASE = "$MYSQL_PATH\$MYSQL_PROD" $MYSQL_PDTA = "$env:ProgramData\$MYSQL_NAME\$MYSQL_PROD" $MYSQL_DATA = "$MYSQL_PDTA\data" $MYSQL_INIT = "$MYSQL_PDTA\mysql-init.sql"
- Download MySQL:
Invoke-WebRequest "$MYSQL_URL" -OutFile "$MYSQL_ZIP.zip"
- Unzip it:
Expand-Archive "$MYSQL_ZIP.zip" "$MYSQL_PATH"
- and install/copy it:
Rename-Item "$MYSQL_PATH\$MYSQL_ZIP" "$MYSQL_BASE"
- Set MySQL “bin” directory to the search Path variable:
$env:Path += ";$MYSQL_BASE\bin" setx Path $env:Path /m
- Create MySQL Option File:
Set-Content "$MYSQL_BASE\my.ini" "[mysqld]`r`nbasedir=""$MYSQL_BASE""`r`ndatadir=""$MYSQL_DATA""`r`nexplicit_defaults_for_timestamp=1"
- Create MySQL database directory:
New-Item $MYSQL_DATA -ItemType Directory | Out-Null
- Initialise MySQL database files:
mysqld --initialize-insecure
- Install and start MySQL as a Windows service:
mysqld --install Start-Service MySQL Get-Service MySQL
- Create a MySQL initialisation script to set a password for the root user (Replace PASSW0RD in the above command with your own strong password.):
Set-Content $MYSQL_INIT "ALTER USER 'root'@'localhost' IDENTIFIED BY 'PASSW0RD';"
- Add the following lines in preparation for running WordPress:
Add-Content $MYSQL_INIT "CREATE DATABASE wordpress;" Add-Content $MYSQL_INIT "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'PASSW0RD';" Add-Content $MYSQL_INIT "GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'localhost';"
- and execute the script:
mysql --user=root --execute="source $MYSQL_INIT"
- delete the script at the end:
Remove-Item $MYSQL_INIT
MySQL is now done setup
Wordpress
- Download and unzip WordPress:
$IIS_PATH = "$env:SystemDrive\inetpub" $WORDPRESS_PATH = "$IIS_PATH\wordpress" $WORDPRESS_URL = "https://wordpress.org/latest.zip" $WORDPRESS_ZIP = "wordpress.zip" Invoke-WebRequest "$WORDPRESS_URL" -OutFile "$WORDPRESS_ZIP" Expand-Archive "$WORDPRESS_ZIP" "$IIS_PATH"
- Grant the modify rights for the following accounts to the WordPress directory:
Add-NTFSAccess $WORDPRESS_PATH IIS_IUSRS Modify Add-NTFSAccess $WORDPRESS_PATH IUSR Modify
- Create a IIS website for WordPress:
$WebAppPool = New-WebAppPool "WordPress" $WebAppPool.managedPipelineMode = "Classic" $WebAppPool.managedRuntimeVersion = "" $WebAppPool | Set-Item New-Website "WordPress" -ApplicationPool "WordPress" -PhysicalPath "$WORDPRESS_PATH" Start-Website "WordPress"
- Remove the “Default Web Site” if you want.
Remove-Website "Default Web Site"
Wordpress is now done setup
Setup Wordpress
- Open localhost or 127.0.0.1 in and web browser
- Select your preferred language
- Click Let’s go
- Complete the Database Connection Details page with the database name “wordpress” and username “wordpress” with passord from the previous step
- Submit
- Enter sitename, email and username along with password (this is your wp-admin login for the site you are creating). Diabling the Search Engine Visibility is up to you. Keep a copy of the credentials you just setup
- Done