
The default WAMP setup hands you http://localhost/myproject/ and lets you ship code that breaks the moment it leaves your laptop. Hardcoded paths to /myproject/, base URLs full of localhost, database links that need a find-and-replace before deploy. The fix is a virtual host: http://mysite.local maps to your project folder on disk, every URL in the app behaves like production, and the database migration on launch day is just a domain swap. The setup has not changed dramatically since the original WAMP, but Apache 2.4 dropped a few legacy directives, modern dev now expects HTTPS on localhost, and the alternatives (XAMPP, Laravel Valet, Docker) have caught up enough that picking WAMP is a deliberate choice. Here is the refreshed walkthrough for WAMP Server 3.3+ on Windows, plus the parts of the toolchain worth knowing about.
How do I set up a virtual host on WAMP Server?
Three files, two restarts. First, edit C:\wamp64\bin\apache\apache2.4.x\conf\extra\httpd-vhosts.conf and add a <VirtualHost *:80> block with ServerName mysite.local and DocumentRoot "c:/wamp64/www/mysite" (plus a matching <Directory> block with Require local). Second, edit C:\Windows\System32\drivers\etc\hosts (as Administrator) and add 127.0.0.1 mysite.local. Third, confirm Include conf/extra/httpd-vhosts.conf is uncommented in httpd.conf (WAMP 3.3 enables it by default). Restart Apache from the WAMP tray icon (left-click WAMP > Apache > Service > Restart Service), flush the DNS cache with ipconfig /flushdns, and http://mysite.local will serve your project. Repeat the <VirtualHost> block for each additional site.
Jump to:
- What WAMP Server looks like in 2026
- Step 1: enable vhost includes in httpd.conf
- Step 2: add a virtual host block
- Step 3: edit the Windows hosts file
- Step 4: restart Apache and verify
- Multiple sites: different domains vs different ports
- HTTPS on localhost with mkcert
- Cross-platform alternatives to WAMP
- Troubleshooting
- What to do next
- FAQ
What WAMP Server looks like in 2026
WAMP Server is still actively maintained by Romain Bourdon (wampserver.com). The current line is WAMP 3.3.x with bundled Apache 2.4, PHP 8.2/8.3/8.4 (you can switch between versions from the tray menu), and MySQL 8 / MariaDB. The default install path moved from C:\wamp\ to C:\wamp64\ years ago, so every path in this guide uses c:/wamp64/, adjust if your install differs.
Two things have changed since the older WAMP docs that float around:
- Apache 2.4 dropped
NameVirtualHost. The legacyNameVirtualHost *:80directive is gone. In 2.4 you just declare<VirtualHost *:80>blocks and Apache handles the name-based matching itself. If you copy a vhost config from a 2.2-era tutorial, delete theNameVirtualHostline. - Apache 2.4 changed authorization syntax.
Order allow,denyandAllow from allare deprecated. UseRequire local(allow loopback only) orRequire all granted(allow anyone). For local dev,Require localis the safer default.
Step 1: enable vhost includes in httpd.conf
Open the main Apache config from the WAMP tray menu:
left-click WAMP icon > Apache > httpd.conf
Find the line near the bottom (around line 540 on Apache 2.4.58):
# Virtual hosts
#Include conf/extra/httpd-vhosts.confUncomment it:
# Virtual hosts
Include conf/extra/httpd-vhosts.confSave the file. On WAMP 3.3+ this is enabled by default, check before editing. Confirming this line is uncommented is the difference between a vhost change taking effect and a vhost change being silently ignored.
If you also see legacy NameVirtualHost *:80 anywhere in httpd.conf (common in older configs upgraded over many WAMP versions), delete it. Apache 2.4 logs a [warn] NameVirtualHost has no effect if you leave it in.
Step 2: add a virtual host block
Open the vhost config from the tray menu:
left-click WAMP icon > Apache > httpd-vhosts.conf
Or directly: C:\wamp64\bin\apache\apache2.4.x\conf\extra\httpd-vhosts.conf.
By default it contains the localhost block that maps http://localhost/ to C:/wamp64/www/. Add your project below it:
<VirtualHost *:80>
ServerName mysite.local
ServerAlias www.mysite.local
DocumentRoot "c:/wamp64/www/mysite"
<Directory "c:/wamp64/www/mysite">
Options +Indexes +FollowSymLinks +MultiViews
AllowOverride All
Require local
</Directory>
ErrorLog "${APACHE_LOG_DIR}/mysite-error.log"
CustomLog "${APACHE_LOG_DIR}/mysite-access.log" common
</VirtualHost>Important bits:
ServerName, the domain you will type in the browser.mysite.localis conventional. Avoid.dev(Google owns the gTLD and Chrome HSTS-pins it to HTTPS, which breaks plain-HTTP local dev). The.localTLD is reserved and safe.ServerAlias, additional names that match this vhost. Useful forwww.variants.DocumentRoot, the absolute filesystem path. Forward slashes work fine on Windows; the colon-after-drive (c:/) is required.AllowOverride All, lets.htaccessfiles in the project override Apache config. WordPress and Laravel need this.Require local, only allow connections from127.0.0.1/::1. Switch toRequire all grantedif you need to reach the dev server from another device on the LAN.ErrorLogandCustomLog, per-site logs go a long way when debugging routing issues. Otherwise everything ends up inapache_error.logmixed with every other site.
Save. Apache parses this file on every restart, a typo here means Apache refuses to start. Check apache_error.log (under C:\wamp64\logs\) if WAMP goes orange or red.
Step 3: edit the Windows hosts file
Apache now knows what to do with mysite.local, but Windows still does not know where to find the host. Map it to loopback in the hosts file:
C:\Windows\System32\drivers\etc\hosts
You need an Administrator text editor to save changes. The trick that works without fail: right-click Notepad in the Start menu > Run as administrator > File > Open > paste the path above > set the file filter to All Files so it shows.
Add a line at the bottom:
127.0.0.1 mysite.local
127.0.0.1 www.mysite.local
Save. Then flush the resolver cache so the change takes effect immediately:
ipconfig /flushdnsBrowsers do their own DNS caching on top of Windows. Chrome's cache lives at chrome://net-internals/#dns and can be flushed from that page if you hit a stale lookup.
Step 4: restart Apache and verify
From the WAMP tray icon: left-click > Apache > Service > Restart Service. The icon goes from orange (restarting) to green (running). If it stays orange, Apache failed to start, check the error log.
Verify with curl or a browser:
curl -I http://mysite.local
# Expected: HTTP/1.1 200 OK (or 403/404 depending on what is at the doc root)If you get HTTP 200, the vhost is working. If you get a DNS error, the hosts file edit did not take (re-flush, or try ping mysite.local to see if it resolves to 127.0.0.1). If you get 403 Forbidden with the right hostname, the <Directory> block is missing or Require local is rejecting your IP, confirm you are connecting from the local machine, not over LAN.
Multiple sites: different domains vs different ports
For each additional site, repeat the <VirtualHost> block with a different ServerName and DocumentRoot:
<VirtualHost *:80>
ServerName client-a.local
DocumentRoot "c:/wamp64/www/client-a"
<Directory "c:/wamp64/www/client-a">
AllowOverride All
Require local
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName client-b.local
DocumentRoot "c:/wamp64/www/client-b"
<Directory "c:/wamp64/www/client-b">
AllowOverride All
Require local
</Directory>
</VirtualHost>And add both to the hosts file:
127.0.0.1 client-a.local
127.0.0.1 client-b.local
This is name-based virtual hosting, Apache uses the Host: header in the HTTP request to pick the right vhost. The *:80 is the listen socket (any address, port 80), and ServerName is the discriminator.
If you need two sites on the same hostname but different ports (rare, usually only when one app refuses to play nice with vhosts):
Listen 80
Listen 8080
<VirtualHost *:80>
ServerName mysite.local
DocumentRoot "c:/wamp64/www/mysite"
</VirtualHost>
<VirtualHost *:8080>
ServerName mysite.local
DocumentRoot "c:/wamp64/www/mysite-admin"
</VirtualHost>Then visit http://mysite.local and http://mysite.local:8080. Less common; mention it because tutorials in the wild still do.
HTTPS on localhost with mkcert
Modern web work needs HTTPS even locally, Service Workers, secure cookies, mixed-content rules, and most modern OAuth flows refuse to run over plain HTTP. The cleanest way to get a locally trusted cert in 2026 is mkcert by Filo Sottile. It installs a local CA into your system trust store and issues per-domain certs that Chrome, Firefox, and Edge accept without warnings.
Install via Chocolatey or Scoop:
# Chocolatey
choco install mkcert
# Or Scoop
scoop install mkcertThen in an Administrator PowerShell:
mkcert -install
cd C:\wamp64\certs
mkdir -p .
mkcert mysite.local "*.mysite.local"That writes mysite.local+1.pem and mysite.local+1-key.pem into the current directory.
Enable Apache's SSL module (WAMP tray > Apache > Apache modules > tick ssl_module) and add an HTTPS vhost:
Listen 443
<VirtualHost *:443>
ServerName mysite.local
DocumentRoot "c:/wamp64/www/mysite"
SSLEngine on
SSLCertificateFile "c:/wamp64/certs/mysite.local+1.pem"
SSLCertificateKeyFile "c:/wamp64/certs/mysite.local+1-key.pem"
<Directory "c:/wamp64/www/mysite">
AllowOverride All
Require local
</Directory>
</VirtualHost>Restart Apache. https://mysite.local now serves with a green padlock, no --ignore-certificate-errors hacks.
If you want an HTTP > HTTPS redirect on local (matching prod behaviour):
<VirtualHost *:80>
ServerName mysite.local
Redirect permanent / https://mysite.local/
</VirtualHost>Cross-platform alternatives to WAMP
WAMP is Windows-only by design. If you also work on macOS or Linux, or want fewer surface areas to maintain, here are the realistic alternatives in 2026:
| Tool | Platform | Strengths | Pick when... |
|---|---|---|---|
| WAMP Server | Windows | One installer, clear tray menu, easy PHP version switching | You are Windows-only and want a GUI |
| XAMPP | Windows, macOS, Linux | Identical experience across platforms, FileZilla and Mercury bundled | You want the same tool across multiple OSes |
| Laravel Valet | macOS, Valet for Linux exists | Zero-config per-project HTTPS via dnsmasq, lightweight | You are on macOS and most projects are Laravel or generic PHP |
| Laragon | Windows | Lighter than WAMP, automatic vhost provisioning, built-in mkcert-style HTTPS | You want WAMP's role with less config |
| Docker Compose | Cross-platform | Real production-like infra, reproducible across the team | You need to match production exactly, or you have a team |
| DDEV | Cross-platform | Docker under the hood but PHP-focused with a CLI that abstracts the YAML | You want Docker's isolation without writing compose files |
| Homebrew Apache + PHP | macOS | Native binaries, no virtualization | You are on macOS and want the simplest possible stack |
My honest take: if you are Windows-only and you like a tray icon, WAMP is fine. If you are on a team that needs the dev environment to match production, switch to Docker (or DDEV if you do not want to write compose files). For solo PHP work on macOS, Laravel Valet is hard to beat, valet park in your code folder and every subdirectory becomes a vhost automatically.
Troubleshooting
WAMP tray icon stays orange (Apache won't start). Open C:\wamp64\logs\apache_error.log. The most common errors are a syntax mistake in your new vhost block (look for [error] AH00526: Syntax error on line X) or a port-80 conflict.
"Port 80 already in use" / AH00072: make_sock: could not bind to address [::]:80. Something else is bound to port 80. Common culprits on Windows: IIS, Skype (older versions), VMware Workstation Server, "World Wide Web Publishing Service". Identify the offender:
netstat -ano | findstr :80
tasklist /FI "PID eq <PID>"Then either stop the service (Stop-Service W3SVC for IIS) or change WAMP to listen on a different port (edit Listen 80 in httpd.conf, then update your hosts file and vhosts accordingly).
Browser shows the WAMP "Server Configuration" landing page instead of my site. The Host header is not matching any vhost. Confirm ServerName mysite.local exactly matches what the browser sends. Look in apache_access.log to see which Host header arrived.
"You don't have permission to access this resource" (403). The <Directory> block is missing or Require local is rejecting the connection. Add a <Directory> block for the DocumentRoot with Require local. If you are accessing from a LAN device, switch to Require all granted and tighten with Require ip 192.168.0.0/16.
.htaccess rewrite rules ignored. AllowOverride None is the default in some Apache configs. Set AllowOverride All in the <Directory> block. Confirm mod_rewrite is enabled (WAMP tray > Apache > Apache modules > rewrite_module ticked).
mysite.local does not resolve. Hosts file edit did not save (you opened Notepad without Admin), or Windows DNS cache is stale. Run ipconfig /flushdns. Confirm with ping mysite.local, it should resolve to 127.0.0.1. If it still does not, Notepad probably saved as hosts.txt; check that the file has no extension.
HTTPS shows certificate warning even with mkcert. mkcert -install did not run as Administrator, so the CA is not in the system trust store. Re-run as Admin. For Firefox specifically, mkcert needs Firefox's NSS to be detected, run mkcert -install after Firefox is installed.
What to do next
- How to Increase PHP Memory Limit, once your project is running under a vhost, this is the next config you will need to tweak.
- How to Export and Import PuTTY Settings, Windows SSH cousin. If you set up WAMP on a new Windows box, PuTTY usually follows.
- Installing VirtualBox Guest Additions on Ubuntu, the alternative path: run a Linux VM with a native LAMP stack instead of WAMP. Useful for matching production exactly.
- SSH Cheat Sheet, for connecting from your WAMP machine to remote staging/prod boxes.
- Bash For Loops, if you end up writing deploy scripts inside Git Bash on Windows or on the remote, these patterns apply.
- External: the Apache 2.4 Virtual Host documentation is the authoritative reference for vhost configuration.



![Bash while loop reference: read files with while IFS= read -r, retry-with-backoff, wait-for-service polling, the subshell-scoping bug fix, the until and select siblings, plus [[ ]] vs [ ] vs (( )) test contexts.](https://techearl.com/cdn-cgi/image/width=1536,format=auto,quality=90/https://images.techearl.com/bash-while-loop/bash-while-loop.jpg?v=2026-04-25T13%3A18%3A00Z)
![Bash conditionals reference: if/elif/else syntax, [ ] vs [[ ]] vs (( )) test contexts, numeric, string, and file operators, the case statement, and the unquoted-variable pitfall.](https://techearl.com/cdn-cgi/image/width=1536,format=auto,quality=90/https://images.techearl.com/bash-if-else/bash-if-else.jpg?v=2026-01-08T11%3A24%3A00Z)
