About this course
About this course
This free course teaches you Nginx from the ground up - no prior server experience needed. You'll start by understanding what a web server actually does, then serve your first static site, master how Nginx matches requests to configuration, and use Nginx as a reverse proxy in front of real applications.
Along the way you'll wire Nginx up to PHP-FPM for PHP and Laravel apps, secure your site with free HTTPS certificates from Let's Encrypt, and make it fast with gzip and caching. Every lesson builds on the previous one, with small, real configuration examples you can copy and try.
By the end you'll be able to write and troubleshoot production-ready Nginx configs for a static site, a Laravel app, and a Node app behind a proxy - and understand every line you wrote.
It's written for developers who deploy and run their own apps, not just read about servers.
Course curriculum
- What is nginx? What is nginx? A fast web server and reverse proxy in plain terms - what it does, where it runs, and why so many sites use it.
- How a web request works How a web request works: the client-server request and response cycle behind every website, and the HTTP mental model you need before nginx.
- Nginx vs Apache Nginx vs Apache for beginners: event-driven vs process-per-request, static file speed, memory use, and when to pick each web server.
- Installing nginx Install nginx on Ubuntu or Debian with apt, plus Docker and WSL notes for Windows and Mac. Verify the install works in your browser.
- Start, stop, and reload nginx Start, stop, and reload nginx with systemctl and nginx -s, check status, and learn the difference between reload and restart without downtime.
- Your first page Edit the default nginx page: find the web root in /var/www/html, change index.html, and see your first nginx page live in the browser.
- The nginx.conf config file structure Find the nginx.conf file location on Linux, learn its default path and structure, and read the file at a glance before you edit it.
- Directives and contexts in nginx Learn nginx directives and contexts - simple vs block directives, main/events/http/server/location, and how nesting and inheritance work.
- include, conf.d and sites-available Nginx sites-available vs sites-enabled explained, plus the include directive and conf.d folder for keeping each site in its own file.
- Testing nginx config safely with nginx -t Run nginx -t to test your nginx config before reload. Learn reload vs restart, what a syntax error looks like, and how to avoid downtime.
- Reading nginx access and error logs Where nginx access and error logs live, what error log levels mean, and how to tail them to debug problems in real time.
- Server blocks What an nginx server block is, why Apache calls it a virtual host, and how to write a minimal server { } block that serves one site.
- listen and server_name How nginx server_name matches the domain and listen sets the port, so one nginx hosts several sites, plus the default_server catch-all.
- root and index How the nginx root directive points at your files and index sets the default page, and exactly how a URL path becomes a real file on disk.
- location basics The nginx location block for beginners: what a prefix location matches, why you would use one, and how it changes rules for part of a URL.
- MIME types How nginx MIME types work: mime.types sets the Content-Type header so browsers know what they got, plus default_type for unknown files.
- Custom error pages Set up nginx custom error pages with error_page: your own 404 and 50x HTML, plus an internal location so the file can't be opened directly.
- autoindex Turn on nginx autoindex to show a directory listing when a folder has no index file, when it is genuinely useful, and why to keep it off.
- alias: serve a directory under a different URL Nginx alias vs root explained: map any folder to a URL path, the difference from root, the trailing-slash rule, and the common doubled-path 404.
- Serving on a custom port Make nginx serve a site on a custom port instead of 80, why the port shows in the URL, the firewall step, and how it differs from a reverse proxy.
- How location matching works The five nginx location match types - prefix, exact =, regex ~ and ~*, and ^~ - and exactly which URLs each one matches, with clear examples.
- Matching priority The exact nginx location priority order: exact = first, then ^~, then regex in file order, then longest prefix. Worked examples that clear up the confusion.
- Serving files with try_files How nginx try_files checks if a file exists, falls back to a folder index, and returns 404 - plus the front-controller fallback pattern for real sites.
- Redirects with return Set up an nginx redirect with return 301 and 302 - move a single path or a whole domain, keep the query string, and know why return beats rewrite.
- Rewrite basics How nginx rewrite rules work with regex captures and the last, break, redirect and permanent flags, plus when to use rewrite instead of return.
- What is a reverse proxy What an nginx reverse proxy is, how a request flows from browser to nginx to your app, and why you put nginx in front of an application.
- proxy_pass Use nginx proxy_pass to forward requests to a Node or other app on a local port, and master the trailing-slash rule that trips people up.
- Passing the real client info Forward the real client IP, host and protocol to your app with nginx proxy_set_header so logging, redirects and rate limits work behind nginx.
- Naming backends with upstream Define an nginx upstream block to name one or more backend servers, then point proxy_pass at the name instead of a hard-coded address.
- Load balancing across backends Set up nginx load balancing across backends: round-robin, weight, least_conn and ip_hash, plus marking servers down or backup.
- How nginx runs PHP How nginx runs PHP with PHP-FPM: nginx never executes PHP, it passes .php requests to PHP-FPM over FastCGI. Follow the full request flow, step by step.
- The fastcgi_pass block The nginx fastcgi_pass PHP-FPM config, line by line: fastcgi_pass, include fastcgi_params, and why SCRIPT_FILENAME picks the file. Unix socket vs TCP.
- A working PHP site A complete nginx PHP-FPM server block example for a plain PHP site: listen, root, try_files, and the FastCGI location. Copy it, add phpinfo, test that PHP runs.
- A Laravel server block The canonical nginx Laravel server block config: root at /public, try_files to index.php, the PHP-FPM location, and dotfile protection, explained line by line.
- Why HTTPS What HTTPS and TLS are, what an SSL certificate proves, and why every website needs HTTPS for security, SEO and to avoid browser warnings.
- listen 443 ssl Enable HTTPS in nginx with listen 443 ssl, ssl_certificate and ssl_certificate_key. See what the cert and private key files are, then test and reload.
- Let's Encrypt with Certbot Get a free HTTPS certificate for nginx with Let's Encrypt and Certbot. certbot --nginx, the HTTP-01 challenge, and automatic renewal with a systemd timer.
- Redirect HTTP to HTTPS Force HTTPS in nginx with a port 80 server block and return 301 https://$host$request_uri. Learn why return beats rewrite and how to avoid loops.
- Basic TLS hardening Beginner-safe nginx TLS hardening: ssl_protocols TLSv1.2 TLSv1.3, ssl_ciphers, ssl_prefer_server_ciphers and an HSTS Strict-Transport-Security header.
- Gzip compression Enable nginx gzip compression to shrink text responses. Set gzip_types, gzip_comp_level, gzip_min_length, and skip what you should never compress.
- Caching static assets Cache static assets in nginx so browsers reuse CSS, JS, and images. Set expires and Cache-Control, pick safe cache times, and handle cache-busting.
- Proxy caching Set up nginx proxy caching with proxy_cache_path and proxy_cache. Cache backend responses, tune proxy_cache_valid, and read the X-Cache-Status header.
- Workers and connections Understand nginx worker_processes and worker_connections: what they control, how they set the connection ceiling, and the defaults you rarely change.
- Keepalive connections Reuse connections with nginx keepalive: keepalive_timeout for clients and upstream keepalive for backends, plus the three lines pooling needs.
- Hide the nginx version Hide the nginx version with server_tokens off so responses and error pages stop leaking it. Where to set the directive and why it matters.
- Restrict access by IP Restrict access by IP in nginx with allow and deny to lock an admin area to office IPs. How CIDR ranges work and why rule order matters.
- Password-protect with basic auth Set up nginx basic auth to password-protect a directory. Create the htpasswd file and add auth_basic to a location, then serve it over HTTPS.
- Rate limiting requests Set up nginx rate limiting with limit_req_zone and limit_req to shield login and API endpoints from floods. How burst, nodelay and limit_conn work.
- Security headers Add nginx security headers with add_header and always: X-Frame-Options, X-Content-Type-Options, Referrer-Policy and a starter CSP.
- A full static site with HTTPS A complete, annotated nginx server block for a static site: HTTP to HTTPS redirect, root, gzip, asset caching, and a custom 404. Every line explained.
- The full Laravel production config The full nginx server block for a Laravel app: HTTPS redirect, root public, try_files front controller, PHP-FPM, gzip, caching, and security headers.
- A Node app behind nginx A complete nginx reverse proxy config for a Node app on 127.0.0.1:3000: HTTPS, proxy headers, upstream keepalive, and WebSocket upgrade headers.
- A troubleshooting checklist Read nginx errors like a pro: fix 502/504, 403, 404, configs that never applied, and redirect loops using nginx -t and the error log. A practical checklist.
- Point a domain at your VPS Point a domain to your VPS the right way: add A and AAAA records for @ and www, wait for DNS propagation, verify with dig, and match it in nginx server_name.
- Deploy a Laravel app from git Deploy a Laravel app from git to a fresh Ubuntu 24.04 VPS: nginx, PHP 8.4-FPM, Composer, MySQL, correct permissions and a production server block, step by step.
- HTTPS with Let's Encrypt Set up free HTTPS on nginx with Let's Encrypt and certbot: install the nginx plugin, open ports 80 and 443, run certbot --nginx, and confirm auto-renewal.
- Nginx 502 Bad Gateway - Causes and Fix Fix nginx 502 Bad Gateway: PHP-FPM down, wrong fastcgi_pass socket, wrong proxy_pass port, or socket permissions. Diagnose with the error log.
- Nginx 413 Request Entity Too Large - Fix Fix nginx 413 Request Entity Too Large: raise client_max_body_size above the default 1M, reload, and bump PHP upload_max_filesize too.
- Nginx 403 Forbidden - Causes and Fix Fix nginx 403 Forbidden: file permissions, missing index file with autoindex off, deny rules, or a wrong root. Diagnose with the error log.
- Nginx 504 Gateway Timeout - Causes and Fix Fix nginx 504 Gateway Timeout: raise fastcgi_read_timeout or proxy_read_timeout, but remember the real fix is usually a slow backend.
- Nginx ERR_TOO_MANY_REDIRECTS - Redirect Loop Fix Fix nginx ERR_TOO_MANY_REDIRECTS: an HTTP to HTTPS loop behind Cloudflare or a proxy. Check X-Forwarded-Proto or switch Cloudflare to Full SSL.
- Nginx bind() to 0.0.0.0:80 failed (98: Address already in use) Fix nginx bind() to 0.0.0.0:80 failed (98: Address already in use): find the service holding port 80 or the duplicate default_server, then reload.
- Nginx Not Serving Static Files - CSS Not Loading Fix Fix nginx not serving static files: wrong root or alias, missing try_files, missing mime.types (CSS as text/plain), permissions, or a greedy front controller.
- Nginx Shows Welcome Page Instead of My Site - Fix Fix nginx showing the default Welcome to nginx page: disable the default site, symlink your config into sites-enabled, match server_name, and reload.