Web Server Configuration
Complete guide to configuring web servers on your VPS. Learn Apache and Nginx setup, optimization, SSL configuration, and security best practices.
- Root or sudo access to your VPS
- Domain name pointed to your server
- Basic understanding of web servers
- Understanding of HTTP/HTTPS protocols
- Backup of current web server configuration
Apache is one of the most popular web servers, known for its flexibility, stability, and extensive module ecosystem.
Apache Features:
- Virtual hosting support
- Extensive module system
- .htaccess configuration
- Wide platform support
- Strong security features
# Install Apache
sudo apt update
sudo apt install apache2 -y
# Start and enable Apache
sudo systemctl start apache2
sudo systemctl enable apache2
# Check status
sudo systemctl status apache2
# Basic configuration files
sudo nano /etc/apache2/apache2.conf
sudo nano /etc/apache2/sites-available/000-default.conf
# Enable essential modules
sudo a2enmod rewrite
sudo a2enmod headers
sudo a2enmod ssl
sudo a2enmod deflate
# Test configuration
sudo apache2ctl configtest
# Restart Apache
sudo systemctl restart apache2
# Check listening ports
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443Nginx is a high-performance web server known for its efficiency, scalability, and modern architecture.
Nginx Advantages:
- Event-driven architecture
- Low memory footprint
- Excellent static file serving
- Built-in load balancing
- Reverse proxy capabilities
# Install Nginx
sudo apt update
sudo apt install nginx -y
# Start and enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
# Check status
sudo systemctl status nginx
# Basic configuration files
sudo nano /etc/nginx/nginx.conf
sudo nano /etc/nginx/sites-available/default
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
# Check listening ports
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443
# Enable essential modules (if needed)
# Nginx modules are compiled in, not loaded like Apache
# Log files
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.logVirtual hosting allows you to host multiple websites on a single server using different domain names or IP addresses.
Virtual Hosting Types:
- Name-based - Multiple domains on same IP
- IP-based - Different IPs for each site
- Port-based - Different ports for each site
# Apache Virtual Host Configuration
# Create new virtual host
sudo nano /etc/apache2/sites-available/example.com.conf
# Add configuration:
# <VirtualHost *:80>
# ServerName example.com
# ServerAlias www.example.com
# DocumentRoot /var/www/example.com/public_html
#
# <Directory /var/www/example.com/public_html>
# AllowOverride All
# Require all granted
# </Directory>
#
# ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
# CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
# </VirtualHost>
# Enable the site
sudo a2ensite example.com.conf
# Disable default site (optional)
sudo a2dissite 000-default.conf
# Create document root
sudo mkdir -p /var/www/example.com/public_html
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
# Restart Apache
sudo systemctl restart apache2
# Nginx Server Block Configuration
# Create new server block
sudo nano /etc/nginx/sites-available/example.com
# Add configuration:
# server {
# listen 80;
# server_name example.com www.example.com;
#
# root /var/www/example.com/public_html;
# index index.html index.htm index.nginx-debian.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#
# location ~ .php$ {
# include snippets/fastcgi-php.conf;
# fastcgi_pass unix:/run/php/php8.1-fpm.sock;
# }
#
# location ~ /.ht {
# deny all;
# }
# }
# Enable the site
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Remove default site (optional)
sudo rm /etc/nginx/sites-enabled/default
# Create document root
sudo mkdir -p /var/www/example.com/public_html
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
# Test and reload
sudo nginx -t
sudo systemctl reload nginxSSL/TLS encryption protects data transmission between your server and clients, essential for security and SEO.
SSL Implementation Methods:
- Self-signed certificates - For testing/development
- Let's Encrypt - Free automated certificates
- Commercial certificates - Paid certificates with warranty
# Install Certbot for Let's Encrypt
sudo apt install certbot python3-certbot-apache python3-certbot-nginx -y
# Apache SSL Configuration
# Get SSL certificate for Apache
sudo certbot --apache -d example.com -d www.example.com
# Manual SSL certificate installation for Apache
sudo nano /etc/apache2/sites-available/example.com-ssl.conf
# <VirtualHost *:443>
# ServerName example.com
# DocumentRoot /var/www/example.com/public_html
#
# SSLEngine on
# SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
# SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
#
# <Directory /var/www/example.com/public_html>
# AllowOverride All
# Require all granted
# </Directory>
# </VirtualHost>
# Enable SSL site
sudo a2ensite example.com-ssl.conf
sudo a2enmod ssl
# Nginx SSL Configuration
# Get SSL certificate for Nginx
sudo certbot --nginx -d example.com -d www.example.com
# Manual SSL configuration for Nginx
sudo nano /etc/nginx/sites-available/example.com
# server {
# listen 443 ssl http2;
# server_name example.com www.example.com;
#
# ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
# ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
#
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
# ssl_prefer_server_ciphers off;
#
# root /var/www/example.com/public_html;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
# }
# Redirect HTTP to HTTPS
# server {
# listen 80;
# server_name example.com www.example.com;
# return 301 https://$server_name$request_uri;
# }
# Test SSL configuration
sudo apache2ctl configtest
sudo nginx -t
# Restart services
sudo systemctl restart apache2
sudo systemctl restart nginx
# Test SSL certificate
openssl s_client -connect example.com:443 -servername example.comWeb server security involves protecting against common attacks, securing configurations, and implementing best practices.
Security Measures:
- Remove server signature
- Disable directory listing
- Implement security headers
- Protect sensitive files
- Configure proper permissions
# Apache Security Configuration
sudo nano /etc/apache2/apache2.conf
# Hide server information
ServerSignature Off
ServerTokens Prod
# Disable directory listing
<Directory /var/www/>
Options -Indexes
AllowOverride All
Require all granted
</Directory>
# Protect sensitive files
<FilesMatch ".(htaccess|htpasswd|ini|log|sh|inc|bak)$">
Order Allow,Deny
Deny from all
</FilesMatch>
# Security headers
<VirtualHost *:80>
# Clickjacking protection
Header always append X-Frame-Options SAMEORIGIN
# XSS protection
Header set X-XSS-Protection "1; mode=block"
# MIME type sniffing protection
Header set X-Content-Type-Options nosniff
# HSTS (HTTP Strict Transport Security)
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
</VirtualHost>
# Nginx Security Configuration
sudo nano /etc/nginx/nginx.conf
# Hide nginx version
server_tokens off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
# Disable directory listing
autoindex off;
# Protect sensitive files
location ~ /. {
deny all;
}
location ~ .(htaccess|htpasswd|ini|log|sh|inc|bak)$ {
deny all;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req zone=api burst=20 nodelay;
# DDoS protection
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_conn conn_limit_per_ip 10;
# File permissions
sudo find /var/www -type f -exec chmod 644 {} ;
sudo find /var/www -type d -exec chmod 755 {} ;
sudo chown -R www-data:www-data /var/www
# Restart services
sudo systemctl restart apache2
sudo systemctl restart nginxWeb server performance optimization involves configuring caching, compression, connection handling, and resource management.
Optimization Areas:
- Static file caching
- Compression (gzip/deflate)
- Connection keep-alive
- Worker process tuning
- PHP optimization
# Apache Performance Optimization
sudo nano /etc/apache2/mods-available/mpm_prefork.conf
# Prefork settings for better performance
<IfModule mpm_prefork_module>
StartServers 4
MinSpareServers 3
MaxSpareServers 10
MaxRequestWorkers 256
MaxConnectionsPerChild 10000
</IfModule>
# Enable compression
sudo a2enmod deflate
sudo nano /etc/apache2/mods-available/deflate.conf
# Compression settings
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
# Browser caching
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/javascript "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
# Nginx Performance Optimization
sudo nano /etc/nginx/nginx.conf
# Worker processes
worker_processes auto;
worker_connections 1024;
# Enable 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/javascript
application/xml+rss
application/json;
# Browser caching
location ~* .(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1M;
add_header Cache-Control "public, immutable";
}
# PHP-FPM optimization
sudo nano /etc/php/8.1/fpm/pool.d/www.conf
# Process management
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
# OPcache configuration
sudo nano /etc/php/8.1/fpm/php.ini
opcache.enable=1
opcache.memory_consumption=256
opcache.max_accelerated_files=7963
opcache.revalidate_freq=0
opcache.save_comments=0
# Restart services
sudo systemctl restart apache2
sudo systemctl restart nginx
sudo systemctl restart php8.1-fpmMonitoring web server performance and troubleshooting issues are essential for maintaining reliable service.
Monitoring Tools:
- Access and error logs
- Performance monitoring
- Resource usage tracking
- Error analysis
- Automated health checks
# Web server log analysis
# Apache logs
sudo tail -f /var/log/apache2/access.log
sudo tail -f /var/log/apache2/error.log
# Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
# Analyze access patterns
sudo grep "404" /var/log/apache2/access.log | head -10
sudo awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10
# Check server status
# Apache server status
sudo a2enmod status
sudo nano /etc/apache2/mods-available/status.conf
# <Location /server-status>
# SetHandler server-status
# Require local
# </Location>
# Nginx status module
sudo nano /etc/nginx/sites-available/default
# location /nginx_status {
# stub_status on;
# access_log off;
# allow 127.0.0.1;
# deny all;
# }
# Performance testing
# Install Apache Bench
sudo apt install apache2-utils -y
# Test server performance
ab -n 1000 -c 10 http://localhost/
# Install siege for load testing
sudo apt install siege -y
siege -c 100 -t 60S http://localhost/
# Monitor resource usage
sudo htop
sudo iotop
sudo nload
# Check for common issues
# High memory usage
ps aux --sort=-%mem | head -10
# High CPU usage
ps aux --sort=-%cpu | head -10
# Disk space issues
df -h
du -sh /var/log/*
# Network issues
sudo netstat -tlnp
sudo ss -tlnp
# PHP errors
sudo tail -f /var/log/php8.1-fpm.log
# Automated monitoring script
sudo nano /usr/local/bin/web_monitor.sh
#!/bin/bash
LOG_FILE="/var/log/web_monitor.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# Check web server status
if systemctl is-active --quiet apache2; then
APACHE_STATUS="running"
else
APACHE_STATUS="stopped"
fi
if systemctl is-active --quiet nginx; then
NGINX_STATUS="running"
else
NGINX_STATUS="stopped"
fi
# Check response time
RESPONSE_TIME=$(curl -o /dev/null -s -w "%{time_total}" http://localhost/)
# Log status
echo "$TIMESTAMP - Apache: $APACHE_STATUS, Nginx: $NGINX_STATUS, Response: ${RESPONSE_TIME}s" >> $LOG_FILE
# Alert on issues
if [ "$APACHE_STATUS" = "stopped" ] && [ "$NGINX_STATUS" = "stopped" ]; then
echo "Web server is down!" | mail -s "Web Server Alert" admin@example.com
fiCan't find what you're looking for? Our support team is here to help.
