Apache Web Server Setup
Apache HTTP Server is a mature web server with a modular architecture. Widely used on shared hosting, integrated with PHP through mod_php or mod_proxy_fcgi, in corporate environments with LDAP/Kerberos.
Installation and basic modules
apt install -y apache2
a2enmod rewrite ssl headers proxy proxy_fcgi setenvif http2
systemctl restart apache2
VirtualHost for Laravel
# /etc/apache2/sites-available/myapp.conf
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/myapp/current/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
Protocols h2 http/1.1
# Security headers
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
<Directory /var/www/myapp/current/public>
AllowOverride All
Require all granted
Options -Indexes
</Directory>
# PHP-FPM via socket
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
# Static assets - cache
<FilesMatch "\.(css|js|jpg|png|gif|ico|svg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/myapp-error.log
CustomLog ${APACHE_LOG_DIR}/myapp-access.log combined
</VirtualHost>
.htaccess for Laravel
# public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# HTTPS redirect (if not handled by VirtualHost)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Allow access to existing files
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# Redirect everything to index.php
RewriteRule ^ index.php [L]
</IfModule>
# Disable server version output
ServerSignature Off
# Deny access to .env
<Files ".env">
Require all denied
</Files>
Performance
# /etc/apache2/mods-enabled/mpm_event.conf
<IfModule mpm_event_module>
StartServers 2
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 150
MaxConnectionsPerChild 0
</IfModule>
# Enable gzip
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css application/json application/javascript
DeflateCompressionLevel 6
</IfModule>
# mod_expires
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
</IfModule>
Rate Limiting via mod_ratelimit
a2enmod ratelimit
# In VirtualHost
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 400 # 400 KB/s
Reverse Proxy
a2enmod proxy proxy_http
<VirtualHost *:443>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Real-IP %{REMOTE_ADDR}s
</VirtualHost>
Apache vs Nginx
Apache is preferable when: .htaccess is needed (shared hosting), mod_php is used, there are complex per-directory configs, specific Apache modules are required. In other cases Nginx shows better performance on static content and lower memory consumption.
Timeline
Basic Apache setup with PHP-FPM: 1 day. Performance and security optimization: +1 day.







