๐Ÿš€ Webserver Essentials for Serving Web Frontends & Backends

Tags: NginX, Apache, Static Serving, Reverse Proxy, Port Forwarding

๐ŸŽฏ Purpose

  • A webserver delivers static web content (HTML, CSS, JS, Imgs) from serverยดs machine to clientโ€™s browser using HTTP/HTTPS.
  • A Reverse Proxy (RP) sits in front of backends running of serversยดmachine and forwards client requests to them.
    ๐Ÿ‘‰ Nginx and Apache can do both.

๐ŸŒฑ Origin

  • Apache HTTP Server: Released in 1995 by the Apache Software Foundation; named from โ€œa patchy serverโ€ due to its many patches.
  • Nginx: Created in 2004 by Igor Sysoev in Russia to handle high concurrency and efficiency; name = โ€œEngine X.โ€

๐Ÿง  Essentials

Webserver Essentials

๐Ÿ› ๏ธ Core Tasks of a Webserver

  • ๐Ÿ“‚ Serve static files (HTML, CSS, JS, images).
  • ๐Ÿ”’ Handle HTTPS/SSL encryption.
  • โšก Optimize performance (cache static content, compress responses, offload SSL/TLS).
  • ๐Ÿ”€ Load balancing: Distributes traffic across multiple backend servers.
  • ๐Ÿ“Š Log requests & errors for monitoring and debugging.
  • ๐Ÿ”€ Forward requests to backend apps (reverse proxy).
  • ๐ŸŒ Manage multiple sites/domains in one server (virtual hosts/server blocks).
  • โ†’ โœ… Why do we need a RP?
  • ๐ŸŒ Single entry point: One domain (e.g., https://wof.com) can serve both frontend (/) and backend (/api). Without it, youโ€™d need different ports/domains.
  • ๐Ÿ”ง Flexibility: Easy to swap or scale backend services without changing the frontend.
  • ๐Ÿ”’ Security: Hides backend servers from the internet, only the RP is exposed.
  • ๐Ÿ‘‰ Without a RP, the frontend must know the exact address/port of the backend, youโ€™d run into CORS issues, and managing multiple services becomes harder.

๐Ÿ”„ Host multiple sites on one server.

  • In Apache called Virtual Hosts and configured in config file httpd-vhosts.conf
    <VirtualHost *:80>
      ServerName example.com
      DocumentRoot /var/www/example
    </VirtualHost>
  • Nginx called Server Blocks and configured in config file /etc/nginx/sites-available/[configname]
    server {
      server_name example.com;
      root /var/www/example;
    }

๐Ÿ“‚ Serving Static Files

  • Copy static files to Webserver deployment Directory, to serve them to browsers
  • In Apache configured in Virtual Host with: DocumentRoot "/opt/lampp/htdocs"
  • In Nginx configured in Server Block with: root /var/www/html;

๐Ÿ”€ Reverse Proxy

  • Configure Proxy-Passing to forward requests to backend apps (Node.js, Pythonโ€ฆ).
  • In Apache configured in Virtual Host with:
      ProxyPreserveHost On
      ProxyPass /api http://localhost:3000/api
      ProxyPassReverse /api http://localhost:3000/api
  • In Nginx configured in Server Block with:
      proxy_pass http://localhost:3000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

๐Ÿ”’ HTTPS / TLS Setup

Letโ€™s Encrypt is a free & automated Certificate Authority (CA) that issues digital certificates to enable HTTPS on websites, making web encryption accessible to everyone.

  1. create certificate
# a. Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx  # Nginx
# OR
sudo apt install certbot python3-certbot-apache # Apache

# b. Request a Letยดs Encrypt Certificate
sudo certbot --nginx -d example.com -d www.example.com # Nginx
# OR
sudo certbot --apache -d example.com -d www.example.com # Apache
# ๐Ÿ‘‰ Certbot: Obtains Letโ€™s Encrypt certificate; Updates server config to use HTTPS and Reloads webserver.

# c. Test Automatic Renewal - certs are valid for 90days with auto-renewal
sudo certbot renew --dry-run
  1. Configure webserver to use SSL certs
  • Apache

    <VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        SSLEngine on
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    </VirtualHost>
    <VirtualHost *:80>
        ServerName example.com
        ServerAlias www.example.com
        Redirect permanent / https://example.com/
    </VirtualHost>
  • Nginx

    server {
      listen 443 ssl;
      ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    }
    server {
        listen 80;
        server_name example.com www.example.com;
        return 301 https://$host$request_uri;
    }
  1. Verify in Browser Open https://example.com โ†’ should show a padlock ๐Ÿ”’.

โšก Performance Basics

  • Enable caching (static assets).
  • Use compression (gzip, Brotli).
  • Prefer Nginx for high concurrency; Apache for flexibility & .htaccess.

๐Ÿ“ฆ Apache deployment (Frontend & Backend)

  • Make
    โ†’ FE UI available on http://localhost/
    โ†’ BE API available on http://localhost/api/
  1. Enable virtual hosts extra config file
# Open file /opt/lampp/etc/httpd.conf
# Comment in following line (remove # at start)
Include etc/extra/httpd-vhosts.conf
  1. Configure Apache Virtual Host
sudo nano /opt/lampp/etc/extra/httpd-vhosts.conf
#Add a VirtualHost with proxy rules
<VirtualHost *:80>
    ServerName localhost

    # Serve static FE files in htdocs/wof directly at http://localhost
    DocumentRoot "/opt/lampp/htdocs/wof"
    <Directory "/opt/lampp/htdocs/wof">
        Require all granted
        AllowOverride All
    </Directory>

    # Forward /api requests to Node.js backend on port 3000
    ProxyPreserveHost On
    ProxyPass /api http://localhost:3000/api
    ProxyPassReverse /api http://localhost:3000/api
</VirtualHost>
  1. Copy frontend static files to DocumentRoot

  2. Restart Apache

# Open XAMPP GUI
sudo /opt/lampp/manager-linux-x64.run
Start/Restart Apache
  1. Fix URLs in FE code
API_URL = 'http://localhost/api'

๐ŸŒ Internet access to web app running on local dev env

Goal: access FE UI over the internet using http://[public-ip:8080/]

Network config local dev env

  1. Fix API_URL in FE to be โ€˜/apiโ€™ (local is always the adr of the caller)

  2. Configure following Port forwarding in virtual box:
    โ†’ [host-private-ip:8080] โ†’ [vm-ip:80]
    โ†’ host-private-ip can be found by running cmd ipconfig /all on Host-Machine

  3. Configure following Port forwarding in router admin panel:
    โ†’ connect to router admin panel and find Port Forwarding section
    โ†’ Add & save new rule [router-public-ip:8080] โ†’ [host-private-ip:8080]

  4. Test internet access to frontend
    โ†’ Use mobile devive not connected to same network as host-machine
    โ†’ Open http://[public-ip:8080/] in browser and play game

  5. Delete Port Forwarding configs after test (security)

All cheat sheets are taken from our Udemy Online Course. Interested? Check out:
All-In-One Full Stack DevOps - From Idea to Cloud