dotlinux guide

Step-by-Step Guide to Setting Up a Linux Web Server

In today’s digital landscape, web servers are the backbone of the internet, powering everything from personal blogs to enterprise applications. Linux, with its open-source nature, robust security, and cost-effectiveness, is the preferred OS for hosting web servers. Whether you’re a developer deploying a application, a small business launching a website, or an enthusiast learning server management, setting up a Linux web server is a foundational skill. This guide will walk you through the entire process—from choosing a Linux distribution to securing, monitoring, and maintaining your server. By the end, you’ll have a production-ready web server capable of hosting dynamic websites, APIs, or static content.

Table of Contents

  1. Choosing a Linux Distribution
  2. Setting Up the Server Environment
  3. Initial Server Hardening
  4. Installing a Web Server Stack (LAMP/LEMP)
  5. Configuring the Web Server
  6. Setting Up a Domain and DNS
  7. Enabling SSL/TLS with Let’s Encrypt
  8. Testing the Server
  9. Security Best Practices
  10. Monitoring and Maintenance
  11. Common Pitfalls and Troubleshooting
  12. Conclusion
  13. References

1. Choosing a Linux Distribution

Linux offers multiple distributions (“distros”), each optimized for specific use cases. For web servers, prioritize stability, long-term support (LTS), and community documentation.

Top Choices:

  • Ubuntu Server LTS: Most popular for beginners; extensive documentation, large community, and 5-year LTS cycles (e.g., 22.04 LTS).
  • Debian: Known for stability; used as the base for Ubuntu. Ideal for production environments requiring minimal overhead.
  • CentOS Stream/Rocky Linux: RHEL-based, enterprise-grade stability; preferred for corporate environments.
  • Alpine Linux: Lightweight (5MB base image); great for containers or resource-constrained servers.

Recommendation: Start with Ubuntu Server LTS for its user-friendly tools and widespread support.

2. Setting Up the Server Environment

Hardware/Infrastructure Options:

  • Physical Server: Dedicated hardware (e.g., a repurposed PC or enterprise-grade server).
  • Virtual Machine (VM): Use VirtualBox, VMware, or Proxmox for local testing.
  • Cloud VPS: AWS EC2, DigitalOcean Droplet, Linode, or Google Cloud Compute Engine (GCE) for production.

Minimum Requirements (for Ubuntu Server):

  • 1 CPU core
  • 1GB RAM (2GB recommended for production)
  • 20GB storage (SSD preferred for speed)
  • Stable internet connection

3. Initial Server Hardening

Before installing services, secure the base OS to minimize attack surfaces.

3.1 Update the System

Always start by updating packages to patch vulnerabilities:

# On Debian/Ubuntu
sudo apt update && sudo apt upgrade -y

# On RHEL/CentOS/Rocky Linux
sudo dnf update -y

3.2 Create a Non-Root User

Running as root is risky. Create a sudo-enabled user:

# Create a new user (replace "webadmin" with your username)
sudo adduser webadmin

# Grant sudo privileges
sudo usermod -aG sudo webadmin

3.3 Secure SSH Access

SSH is the primary way to manage Linux servers. Harden it by:

3.3.1 Disable Password Authentication (Use SSH Keys)

Passwords are vulnerable to brute-force attacks. Use SSH keys instead:

On your local machine, generate an SSH key pair (if you don’t have one):

ssh-keygen -t ed25519  # Ed25519 is more secure than RSA

Copy the public key to the server (replace webadmin and SERVER_IP):

ssh-copy-id webadmin@SERVER_IP

3.3.2 Configure SSH Daemon (sshd_config)

Edit the SSH config file:

sudo nano /etc/ssh/sshd_config

Set these values:

PermitRootLogin no               # Disable root SSH access
PasswordAuthentication no        # Disable password logins
PubkeyAuthentication yes         # Enable SSH keys
Port 2222                        # Optional: Change port (e.g., 2222) to avoid scans
AllowUsers webadmin              # Restrict SSH to specific users

Restart SSH to apply changes:

sudo systemctl restart sshd

3.4 Enable a Firewall

Use ufw (Uncomplicated Firewall) to restrict network access:

# Enable UFW
sudo ufw enable

# Allow SSH (adjust port if changed earlier)
sudo ufw allow ssh  # or sudo ufw allow 2222/tcp

# Allow HTTP (80) and HTTPS (443) for web traffic
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Verify rules
sudo ufw status

4. Installing a Web Server Stack (LAMP/LEMP)

A web server stack combines:

  • Web Server: Apache or Nginx (handles HTTP requests).
  • Database: MySQL/MariaDB or PostgreSQL (stores dynamic data).
  • Programming Language: PHP, Python, or Node.js (runs server-side code).

4.1 LAMP Stack (Linux, Apache, MySQL, PHP)

Apache is the most widely used web server, known for flexibility.

Install Apache:

sudo apt install apache2 -y

# Enable and start the service
sudo systemctl enable --now apache2

# Verify status
sudo systemctl status apache2  # Should show "active (running)"

Install MySQL/MariaDB

Use MariaDB (a drop-in MySQL replacement) for better community support:

# Install MariaDB
sudo apt install mariadb-server -y

# Secure the installation (sets root password, disables remote root login, etc.)
sudo mysql_secure_installation

Verify: Log into MariaDB with sudo mysql -u root -p (enter the password set earlier).

Install PHP

PHP is required for dynamic content (e.g., WordPress, Laravel):

# Install PHP and Apache PHP module (replace 8.1 with your version)
sudo apt install php libapache2-mod-php php-mysql -y

# Restart Apache to load PHP
sudo systemctl restart apache2

Test PHP: Create a phpinfo.php file in the web root to verify:

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/phpinfo.php

Visit http://SERVER_IP/phpinfo.php in a browser. You should see PHP configuration details.

4.2 LEMP Stack (Alternative: Linux, Nginx, MySQL, PHP)

Nginx is faster for static content and uses less memory than Apache. To use Nginx instead:

# Install Nginx
sudo apt install nginx -y
sudo systemctl enable --now nginx

# Install PHP-FPM (Nginx uses PHP-FPM instead of mod_php)
sudo apt install php-fpm php-mysql -y

# Configure Nginx to use PHP-FPM (see Section 5.2 for details)

4. Configuring the Web Server

4.1 Apache Configuration

Virtual Hosts (Host Multiple Sites)

Apache uses virtual hosts to serve multiple domains from one server.

  1. Create a document root for your site (replace example.com with your domain):

    sudo mkdir -p /var/www/example.com/html
    sudo chown -R $USER:$USER /var/www/example.com/html  # Grant ownership to your user
    sudo chmod -R 755 /var/www  # Ensure read access
  2. Create a sample index file:

    echo "<h1>Welcome to example.com!</h1>" | sudo tee /var/www/example.com/html/index.html
  3. Create a virtual host config file:

    sudo nano /etc/apache2/sites-available/example.com.conf

    Add this configuration:

    <VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName example.com
        ServerAlias www.example.com
        DocumentRoot /var/www/example.com/html
    
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
  4. Enable the site and reload Apache:

    sudo a2ensite example.com.conf  # Enable the site
    sudo a2dissite 000-default.conf  # Disable the default site (optional)
    sudo apache2ctl configtest  # Check for syntax errors
    sudo systemctl reload apache2

4.2 Nginx Configuration

Nginx uses server blocks (equivalent to Apache virtual hosts).

  1. Create a document root (same as Apache step above).

  2. Create a server block config file:

    sudo nano /etc/nginx/sites-available/example.com.conf

    Add this (adjust php8.1-fpm to match your PHP version):

    server {
        listen 80;
        server_name example.com www.example.com;
     
        root /var/www/example.com/html;  
        index index.html index.php;
     
        location / {
            try_files $uri $uri/ =404;
        }
     
        # Enable PHP-FPM (uncomment if using PHP)
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.1-fpm.sock;  
        }
    }  
  3. Enable the server block:

    sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/  
    sudo nginx -t  # Test config syntax  
    sudo systemctl reload nginx  

6. Setting Up a Domain and DNS

To access your server via a domain (e.g., example.com):

6.1 Purchase a Domain

Use registrars like Namecheap, GoDaddy, or Cloudflare.

6.2 Configure DNS Records

Point your domain to your server’s public IP using DNS A/AAAA records.

  1. Find your server’s public IP:

    curl ifconfig.me  # For cloud VPS/local servers with public IP
  2. Add DNS Records (via your domain registrar’s dashboard):

    • A Record: @SERVER_IP (points example.com to your server).
    • A Record: wwwSERVER_IP (points www.example.com to your server).

DNS changes take 10 minutes to 48 hours to propagate globally. Verify with:

nslookup example.com  # Check if the domain resolves to your IP

7. Enabling SSL/TLS with Let’s Encrypt

HTTPS encrypts traffic between the server and clients. Use Let’s Encrypt for free SSL certificates.

Install Certbot

# On Ubuntu/Debian (Apache)
sudo apt install certbot python3-certbot-apache -y

# For Nginx
sudo apt install certbot python3-certbot-nginx -y

Obtain and Install SSL Certificate

Certbot automates SSL setup:

# For Apache
sudo certbot --apache -d example.com -d www.example.com

# For Nginx
sudo certbot --nginx -d example.com -d www.example.com

Follow the prompts to agree to terms, enter an email, and enable HTTPS redirection (recommended).

Verify: Certbot renews certificates automatically (90-day lifespan). Test renewal with:

sudo certbot renew --dry-run

8. Testing the Server

Verify Access:

  • Visit https://example.com in a browser. You should see your index.html content.
  • Check SSL status with SSL Labs Test (should get an “A” grade).

Test PHP (if installed):

Create a test.php file in /var/www/example.com/html:

<?php echo "PHP is working on " . $_SERVER['SERVER_NAME']; ?>

Visit https://example.com/test.php—it should display the message.

9. Security Best Practices

9.1 Firewall Rules

Restrict ports to only what’s needed:

sudo ufw allow ssh  # Only allow SSH, HTTP (80), HTTPS (443)  
sudo ufw deny 23/tcp  # Block insecure ports (e.g., Telnet)

9.2 Install Fail2Ban

Prevent brute-force SSH attacks:

sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban

9.3 Secure PHP

Edit php.ini to disable dangerous functions:

sudo nano /etc/php/8.1/apache2/php.ini  # For Apache
# OR
sudo nano /etc/php/8.1/fpm/php.ini  # For Nginx/PHP-FPM

Set:

disable_functions = exec,passthru,shell_exec,system  # Block code execution
expose_php = Off  # Hide PHP version
allow_url_fopen = Off  # Prevent remote file inclusion

9.4 Database Security

  • Create limited database users (avoid using root for apps):
    CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'StrongPassword123!';  
    GRANT ALL PRIVILEGES ON appdb.* TO 'appuser'@'localhost';  
    FLUSH PRIVILEGES;

10. Monitoring and Maintenance

10.1 Basic Monitoring

  • Resource Usage: Use htop (interactive process viewer):
    sudo apt install htop -y  
    htop  
  • Web Server Status:
    • Apache: sudo systemctl status apache2 or apache2ctl status
    • Nginx: sudo systemctl status nginx or nginx -V

10.2 Advanced Monitoring

  • Prometheus + Grafana: Track metrics (CPU, memory, requests) with a dashboard.
  • ELK Stack: Log aggregation (Elasticsearch, Logstash, Kibana).

10.3 Maintenance Tasks

  • Backups: Use rsync or borgbackup to back up /var/www and databases:
    # Backup MySQL database  
    sudo mysqldump -u root -p --all-databases > backup_$(date +%F).sql  
  • Log Rotation: Linux automatically rotates logs (via logrotate), but verify settings in /etc/logrotate.d/.

Common Pitfalls and Troubleshooting

403 Forbidden Error**:

  • Check file permissions (chmod/chown on /var/www).
  • Ensure Apache/Nginx has read access to the document root.

SSL Certificate Not Renewing**:

  • Verify Certbot cron job exists (sudo crontab -l).
  • Check firewall rules blocking port 80 (required for Let’s Encrypt renewal).

Slow Server Performance**:

  • Use htop to identify resource-heavy processes (e.g., misconfigured PHP scripts).
  • Enable caching (Apache: mod_cache; Nginx: proxy_cache).

12. Conclusion

Setting up a Linux web server involves careful planning—from choosing a distro to securing and maintaining the environment. By following this guide, you’ve built a secure foundation for hosting websites or applications.

Next steps:** Explore server-side technologies**(Node.js/Python),** containerization**(Docker), ororchestration(Kubernetes). Always stay updated on security patches and best practices!

13. References