Skip to main content

Virtual Host Setup

A complete end-to-end reference for creating new sites in OpenLiteSpeed entirely from the CLI.


Mental Model​

Listener (:80 / :443)
└── Domain mapping: "example.com" → vhost "example"
└── Virtual Host "example"
├── docRoot: /var/www/example.com/public
├── scriptHandler: .php → lsphp84 (via LSAPI)
└── rewrite rules / contexts

The listener accepts connections. The domain mapping routes by hostname. The virtual host defines what happens per site.


Step-by-Step: New Site from CLI​

Step 1 — Create Directory Structure​

DOMAIN="example.com"
WEB_ROOT="/var/www/$DOMAIN/public"
VH_CONF_DIR="/usr/local/lsws/conf/vhosts/$DOMAIN"

# Create dirs
sudo mkdir -p "$WEB_ROOT" "$VH_CONF_DIR"

# Set ownership (OLS worker user is nobody:nogroup by default)
sudo chown -R nobody:nogroup "/var/www/$DOMAIN"
sudo chmod -R 755 "/var/www/$DOMAIN"

# Test index page
echo "<h1>$DOMAIN on OpenLiteSpeed</h1>" | sudo tee "$WEB_ROOT/index.html"

Step 2 — Write vhconf.conf​

sudo tee "$VH_CONF_DIR/vhconf.conf" > /dev/null <<CONF
docRoot $WEB_ROOT
vhDomain $DOMAIN, www.$DOMAIN
enableGzip 1
enableBr 1

index {
useServer 0
indexFiles index.php, index.html
}

scripthandler {
add lsapi:lsphp84 php
}

accessControl {
allow *
}

rewrite {
enable 1
autoLoadHtaccess 1
}
CONF

echo "[✓] vhconf.conf written"
cat "$VH_CONF_DIR/vhconf.conf"

Step 3 — Register Vhost in httpd_config.conf​

Open the main config and add a virtualhost block:

sudo vim /usr/local/lsws/conf/httpd_config.conf

Add this block (replace example with your actual name):

virtualhost example {
vhRoot /usr/local/lsws/conf/vhosts/example/
configFile $VH_ROOT/vhconf.conf
allowSymbolLink 1
enableScript 1
restrained 0
}

Also add/update the listener mapping block to reference this vhost:

listener HTTP {
address *:80
secure 0
map example example.com, www.example.com
}

Step 4 — Graceful Reload and Verify​

# Apply changes without downtime
sudo /usr/local/lsws/bin/lswsctrl restart

# Check for errors
sudo tail -20 /usr/local/lsws/logs/error.log

# Test the site
curl -H "Host: example.com" http://localhost/

# Should return 200 with your index page
curl -H "Host: example.com" -s http://localhost/ | head -5

WordPress-Specific vhconf.conf​

vhconf.conf for WordPress
docRoot /var/www/example.com/public
vhDomain example.com, www.example.com
enableGzip 1
enableBr 1

index {
useServer 0
indexFiles index.php, index.html
}

scripthandler {
add lsapi:lsphp84 php
}

accessControl {
allow *
}

rewrite {
enable 1
autoLoadHtaccess 1

rules <<<END_RULES
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
END_RULES
}

The WordPress rewrite rules go in .htaccess:

/var/www/example.com/public/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Multiple PHP Versions Per Vhost​

You can assign a different PHP version per virtual host by creating separate external app entries in httpd_config.conf and mapping each vhost to its version.

httpd_config.conf — two PHP versions
# PHP 8.4 external app
extprocessor lsphp84 {
type lsapi
address uds://tmp/lshttpd/lsphp84.sock
path /usr/local/lsws/lsphp84/bin/lsphp
maxConns 35
env PHP_LSAPI_CHILDREN=35
}

# PHP 8.1 external app (for legacy site)
extprocessor lsphp81 {
type lsapi
address uds://tmp/lshttpd/lsphp81.sock
path /usr/local/lsws/lsphp81/bin/lsphp
maxConns 20
env PHP_LSAPI_CHILDREN=20
}

Then in each vhost's vhconf.conf:

# For the PHP 8.4 site
scripthandler {
add lsapi:lsphp84 php
}

# For the PHP 8.1 site (different vhost file)
scripthandler {
add lsapi:lsphp81 php
}

Domain Mapping Cheatsheet​

Scenariolistener map directive
Single domainmap example example.com
Domain + wwwmap example example.com, www.example.com
Wildcard subdomainmap example *.example.com
Multiple vhosts on one listenerOne map line per vhost

Common Vhost Mistakes​

MistakeSymptomFix
Forgot map in listenerDefault page loadsAdd map vhostname domain.com in listener block
Wrong docRoot path404 on all pagesVerify path exists: ls -la /var/www/...
Permissions not nobody:nogroup403 Forbiddenchown -R nobody:nogroup /var/www/site
No index file in docRoot403 on root URLCreate index.html or index.php
PHP handler missing.php files downloadAdd scripthandler { add lsapi:lsphp84 php }
Vhost not in httpd_config.conf404 for domainAdd virtualhost block in main config
Didn't reload after changesOld config still runninglswsctrl restart

Batch: List All Active Vhosts​

# List all configured vhost names
grep -A1 "^virtualhost" /usr/local/lsws/conf/httpd_config.conf | grep -v "^--" | grep -v "^virtualhost"

# List all vhost conf dirs
ls /usr/local/lsws/conf/vhosts/

# Check domain mappings in all listeners
grep -A3 "^listener" /usr/local/lsws/conf/httpd_config.conf | grep map