Skip to main content

Web Server Configuration

This page provides detailed web server configurations for running Mumara Campaigns.

Apache Configuration

Basic Virtual Host

<VirtualHost *:80>
ServerName campaigns.yourdomain.com
DocumentRoot /var/www/mumara/public

<Directory /var/www/mumara/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

# Logging
ErrorLog ${APACHE_LOG_DIR}/mumara_error.log
CustomLog ${APACHE_LOG_DIR}/mumara_access.log combined
</VirtualHost>

SSL Virtual Host

<VirtualHost *:443>
ServerName campaigns.yourdomain.com
DocumentRoot /var/www/mumara/public

<Directory /var/www/mumara/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>

# SSL Configuration
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/campaigns.yourdomain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/campaigns.yourdomain.com/privkey.pem

# Security Headers
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"

# Logging
ErrorLog ${APACHE_LOG_DIR}/mumara_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/mumara_ssl_access.log combined
</VirtualHost>

# Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName campaigns.yourdomain.com
Redirect permanent / https://campaigns.yourdomain.com/
</VirtualHost>

Required Apache Modules

Enable these modules:

sudo a2enmod rewrite
sudo a2enmod ssl
sudo a2enmod headers
sudo systemctl reload apache2

.htaccess File

The public/.htaccess file should contain:

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>

RewriteEngine On

# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]

# Send Requests To Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

# Protect sensitive files
<FilesMatch "^\.env">
Order allow,deny
Deny from all
</FilesMatch>

<FilesMatch "\.(sql|log)$">
Order allow,deny
Deny from all
</FilesMatch>

Nginx Configuration

Basic Server Block

server {
listen 80;
listen [::]:80;
server_name campaigns.yourdomain.com;
root /var/www/mumara/public;

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";

index index.php;

charset utf-8;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }

error_page 404 /index.php;

location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}

location ~ /\.(?!well-known).* {
deny all;
}

# Deny access to sensitive files
location ~ /\.(env|log|sql) {
deny all;
}
}

SSL Server Block

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name campaigns.yourdomain.com;
root /var/www/mumara/public;

# SSL Certificate
ssl_certificate /etc/letsencrypt/live/campaigns.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/campaigns.yourdomain.com/privkey.pem;

# SSL Configuration
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

index index.php;
charset utf-8;

# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml application/javascript;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }

error_page 404 /index.php;

location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;

# Timeouts for long-running scripts
fastcgi_read_timeout 300;
}

# Static file caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}

location ~ /\.(?!well-known).* {
deny all;
}

location ~ /\.(env|log|sql) {
deny all;
}
}

# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name campaigns.yourdomain.com;
return 301 https://$server_name$request_uri;
}

PHP-FPM Pool Configuration

Create or modify /etc/php/8.3/fpm/pool.d/mumara.conf:

[mumara]
user = www-data
group = www-data

listen = /var/run/php/php8.3-fpm-mumara.sock
listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500

php_admin_value[error_log] = /var/log/php/mumara-error.log
php_admin_flag[log_errors] = on

php_value[memory_limit] = 512M
php_value[max_execution_time] = 300
php_value[upload_max_filesize] = 50M
php_value[post_max_size] = 50M

Performance Optimization

Enable OPcache

In php.ini:

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=0
opcache.validate_timestamps=0 # Set to 1 in development

Configure Redis

For session and cache handling, update your .env:

CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Testing Configuration

Apache

sudo apachectl configtest
sudo systemctl reload apache2

Nginx

sudo nginx -t
sudo systemctl reload nginx

PHP-FPM

sudo php-fpm8.3 -t
sudo systemctl reload php8.3-fpm

Common Issues

502 Bad Gateway (Nginx)

Check PHP-FPM socket path matches nginx config:

ls -la /var/run/php/

Permission Denied

Ensure web server user owns the files:

sudo chown -R www-data:www-data /var/www/mumara

Slow Performance

  • Enable OPcache
  • Use Redis for caching
  • Configure appropriate PHP-FPM workers
  • Enable gzip compression

Next Steps