When working with Apache, you might need to set environment variables dynamically based on the HTTP Host header. This is particularly useful for:
- Environment-specific configuration (DEV/STAGE/PROD)
- Routing requests differently based on domains
- Implementing domain-based feature flags
The proper way to achieve this is using SetEnvIf
with the Host
header:
# In your Apache config or .htaccess
SetEnvIf Host ^dev\.example\.com$ ENV=DEV
SetEnvIf Host ^prod\.example\.com$ ENV=PRD
Here's a full configuration example that covers multiple environments:
<IfModule mod_setenvif.c>
# Development environment
SetEnvIf Host ^dev\.example\.com$ ENV=DEV
# Staging environment
SetEnvIf Host ^stage\.example\.com$ ENV=STAGE
# Production environment
SetEnvIf Host ^(www\.)?example\.com$ ENV=PRD
# Alternative domains
SetEnvIf Host ^example\.net$ ENV=PRD
</IfModule>
After setting the environment variable, you can access it in PHP:
<?php
// Check the environment
if (getenv('ENV') === 'DEV') {
// Development-specific code
error_reporting(E_ALL);
ini_set('display_errors', 1);
} elseif (getenv('ENV') === 'PRD') {
// Production-specific code
error_reporting(0);
ini_set('display_errors', 0);
}
?>
Issue: Variables not being set
Solution: Ensure mod_setenvif is loaded. Check with:
apachectl -M | grep setenvif
Issue: Host matching not working
Solution: Use proper regex anchors. The pattern ^dev\.example\.com$
matches exactly "dev.example.com"
You can combine multiple conditions:
SetEnvIf Host ^dev\.example\.com$ ENV=DEV
SetEnvIf X-Forwarded-Proto https HTTPS=on
Or set multiple variables at once:
SetEnvIf Host ^dev\.example\.com$ ENV=DEV DEBUG=true
While SetEnvIf is powerful, remember:
- Complex regex patterns can impact performance
- Variables are set per-request
- Consider caching environment detection if used frequently
When configuring Apache web servers, developers often need to set environment variables dynamically based on the incoming HTTP Host header. This is particularly useful for:
- Environment detection (DEV/STAGE/PROD)
- Multi-tenant applications
- Domain-specific configuration
The proper way to use SetEnvIf with the Host header is:
SetEnvIfNoCase Host ^dev\.example\.com$ ENV=DEV
SetEnvIfNoCase Host ^prd\.example\.com$ ENV=PRD
Here's a full virtual host configuration example:
<VirtualHost *:80>
ServerName dev.example.com
ServerAlias prd.example.com
# Environment detection
SetEnvIfNoCase Host ^dev\.example\.com$ ENV=DEV
SetEnvIfNoCase Host ^prd\.example\.com$ ENV=PRD
# Fallback for other domains
SetEnvIfNoCase Host ^.*$ ENV=UNKNOWN
DocumentRoot /var/www/html
</VirtualHost>
In your PHP application, you can access this variable through:
<?php
$environment = $_SERVER['ENV'] ?? 'UNKNOWN';
if ($environment === 'DEV') {
// Development-specific logic
error_reporting(E_ALL);
ini_set('display_errors', 1);
} elseif ($environment === 'PRD') {
// Production-specific logic
error_reporting(0);
ini_set('display_errors', 0);
}
?>
Problem: Variables not appearing in $_SERVER
Solution: Ensure mod_setenvif is enabled with:
a2enmod setenvif && service apache2 restart
Problem: Host header matching fails
Solution: Use regex anchors properly and escape dots:
SetEnvIfNoCase Host ^sub\.domain\.com$
For more complex scenarios, you can combine multiple conditions:
# For staging subdomains
SetEnvIfNoCase Host ^staging-[0-9]+\.example\.com$ ENV=STAGE
# For IP-based access
SetEnvIf Remote_Addr ^192\.168\.1\. ENV=LOCAL