NGINX, pronounced “engine x,” is open-source software commonly used as a web server, reverse proxy, content cache, load balancer, TCP/UDP proxy, and mail proxy. It can serve static files directly or sit in front of an application server to receive client requests and forward them to the appropriate backend service.
This NGINX tutorial covers installation, configuration files, static websites, reverse proxying, load balancing, Docker, HTTPS preparation, service management, access logs, and common troubleshooting commands.
What NGINX is used for
NGINX can perform several roles in a web application architecture:
- Static web server: delivers HTML, CSS, JavaScript, images, and downloadable files.
- Reverse proxy: forwards incoming requests to application servers such as Node.js, Java, Python, PHP, Ruby, or .NET services.
- Load balancer: distributes requests among multiple backend servers.
- Content cache: stores selected upstream responses to reduce repeated backend work.
- TLS endpoint: accepts HTTPS connections and forwards requests to internal services.
- TCP and UDP proxy: routes non-HTTP network traffic when the required modules are available.
NGINX uses a master process to read configuration and manage one or more worker processes. The worker processes handle connections and requests.
NGINX Open Source and NGINX Plus
NGINX Open Source is free software that provides the core web server, proxy, caching, and load-balancing capabilities. NGINX Plus is a commercial product from F5 that adds supported enterprise features and services. The examples in this tutorial use directives available in NGINX Open Source unless otherwise stated.
Install NGINX on Ubuntu or Debian
Update the package index and install the distribution-provided NGINX package:
sudo apt update
sudo apt install nginx
Start NGINX and configure it to start during system boot:
sudo systemctl enable --now nginx
sudo systemctl status nginx
Check the installed version:
nginx -v
Open the server IP address or domain name in a browser. A default NGINX page normally appears when the service is running and port 80 is reachable.
Install NGINX on RHEL-compatible Linux
On distributions that use DNF, install and start NGINX with:
sudo dnf install nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx
Package names, repositories, and firewall defaults vary by distribution. The official NGINX Linux packages page lists supported platforms and installation instructions for official packages.
Run NGINX with Docker
The official NGINX container image can serve a local directory without installing NGINX directly on the host. Create a directory containing an index.html file, then mount it into the container:
docker run --name tutorial-nginx \
-p 8080:80 \
-v "$PWD/site:/usr/share/nginx/html:ro" \
-d nginx
Open http://localhost:8080 to view the site. Inspect the container logs with:
docker logs tutorial-nginx
Important NGINX configuration paths
File locations depend on the operating system and installation method. Common paths on Ubuntu and Debian include:
| Path | Purpose |
|---|---|
/etc/nginx/nginx.conf | Main NGINX configuration file |
/etc/nginx/sites-available/ | Stores available server-block configurations |
/etc/nginx/sites-enabled/ | Contains enabled server-block links |
/etc/nginx/conf.d/ | Stores additional configuration files |
/var/www/html/ | Common default document root |
/var/log/nginx/access.log | Default HTTP access log |
/var/log/nginx/error.log | Default error log |
Inspect the active configuration and compiled paths on the current server instead of assuming that every installation uses the same layout.
sudo nginx -T
Understand the NGINX configuration structure
NGINX configuration consists of directives grouped into contexts. Common contexts include events, http, server, and location.
events {
# Connection-processing directives
}
http {
server {
listen 80;
server_name example.com;
location / {
# Request-processing directives
}
}
}
eventscontains connection-processing settings.httpcontains HTTP server, proxy, logging, compression, and related settings.serverdefines a virtual server that listens for requests.locationselects how matching request URIs are processed.
Configure an NGINX static website
Create a document root and an example page:
sudo mkdir -p /var/www/example.com
sudo nano /var/www/example.com/index.html
Add a basic HTML document:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example Site</title>
</head>
<body>
<h1>NGINX is serving this page</h1>
</body>
</html>
Create a server block for the domain:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
On Ubuntu or Debian, save the file as /etc/nginx/sites-available/example.com, then enable it with a symbolic link:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
sudo nginx -t
sudo systemctl reload nginx
The domain’s DNS records must point to the server before public requests can reach this configuration.
Configure NGINX as a reverse proxy
A reverse proxy receives a client request and passes it to an upstream application. The following server block forwards requests to an application listening on local port 3000:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1: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;
}
}
The forwarded headers give the application information about the original request. The application must be configured to trust proxy headers only from expected proxy servers.
The URI handling of proxy_pass changes depending on whether its URL contains a trailing path. Test location and upstream combinations carefully when mounting an application below a path such as /api/.
Reverse proxy an application under /api/
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
In this example, the matching /api/ prefix is replaced by / when the request is passed upstream. Review the official NGINX reverse proxy documentation before choosing URI-rewrite behavior for a production application.
Configure NGINX load balancing
Define a named upstream group and pass requests to it:
upstream application_servers {
server 10.0.0.11:8080;
server 10.0.0.12:8080;
server 10.0.0.13:8080;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://application_servers;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Without another balancing method, requests are distributed using round-robin selection. Other available methods and parameters depend on the NGINX edition, version, and loaded modules.
Use least-connections load balancing
upstream application_servers {
least_conn;
server 10.0.0.11:8080;
server 10.0.0.12:8080;
server 10.0.0.13:8080;
}
The least_conn method directs a request to a server with fewer active connections, while considering configured server weights.
Add basic NGINX proxy timeouts
Proxy timeouts should reflect expected application behavior rather than being increased without diagnosis. The following example sets explicit connection, send, and response-read timeouts:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_connect_timeout 5s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
A gateway timeout may indicate a slow application, blocked network connection, overloaded backend, or timeout that is shorter than a legitimate operation. Check upstream logs before changing the values.
Prepare NGINX for HTTPS
HTTPS requires a valid certificate and private key for the domain. Certificate automation tools can create and renew certificates, but the exact procedure depends on the operating system and certificate authority.
A simplified TLS server block has this structure:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/private-key.pem;
root /var/www/example.com;
index index.html;
}
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
Do not copy placeholder certificate paths into an active configuration. Protect private-key files, test certificate renewal, and use current TLS guidance for the installed NGINX and cryptographic library versions.
Test and reload NGINX configuration safely
Always validate configuration syntax before reloading the service:
sudo nginx -t
sudo systemctl reload nginx
A successful syntax test commonly reports that the configuration syntax is valid and the test completed successfully:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
A reload asks NGINX to apply the new configuration without abruptly stopping normal request processing. A restart stops and starts the service and is usually unnecessary for routine configuration changes.
NGINX service and command reference
| Command | Purpose |
|---|---|
sudo nginx -t | Test configuration syntax |
sudo nginx -T | Test and print the complete active configuration |
sudo systemctl status nginx | Display service status |
sudo systemctl reload nginx | Reload configuration |
sudo systemctl restart nginx | Restart the service |
sudo systemctl stop nginx | Stop the service |
nginx -v | Display the short version |
nginx -V | Display version, compiler, and build arguments |
Read NGINX access and error logs
Logs are the first place to check when a request fails or NGINX does not start.
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
Systemd installations may also record service messages in the journal:
sudo journalctl -u nginx --since "30 minutes ago"
sudo journalctl -u nginx -f
Troubleshoot common NGINX errors
NGINX displays 502 Bad Gateway
A 502 response usually means NGINX could not obtain a valid response from the configured upstream. Check whether the application is running, whether its address and port match proxy_pass, and whether local firewall or permission rules block the connection.
curl -v http://127.0.0.1:3000/
sudo ss -lntp
sudo tail -n 100 /var/log/nginx/error.log
NGINX displays 403 Forbidden
A 403 response can result from file permissions, directory permissions, access-control directives, a missing index file when directory listing is disabled, or operating-system security controls. Confirm that the NGINX worker user can traverse the parent directories and read the requested file.
NGINX displays 404 Not Found
Check the active root or alias directive, the requested URI, the selected server block, and any try_files rule. Use nginx -T to verify the configuration that NGINX actually loaded.
NGINX cannot bind to port 80 or 443
Another process may already be listening on the port. Identify listeners before stopping or reconfiguring services:
sudo ss -lntp | grep -E ':80|:443'
NGINX configuration test fails
Read the file name and line number in the error message. Typical causes include a missing semicolon, an unmatched brace, an invalid directive context, a duplicate listen configuration, or a referenced certificate or include file that does not exist.
Why the default NGINX page appears
The default NGINX page usually means that NGINX is running but the request matched its default server configuration instead of the intended website. Common causes include:
- The domain’s DNS record points to the wrong server.
- The requested hostname is missing from
server_name. - The intended server block has not been enabled or included.
- NGINX was not reloaded after the configuration changed.
- A different server block is acting as the default for that address and port.
Check the hostname sent by the client and inspect the complete active configuration:
curl -I http://example.com
sudo nginx -T
NGINX vs Apache HTTP Server
| Aspect | NGINX | Apache HTTP Server |
|---|---|---|
| Request handling | Uses an event-driven architecture | Supports multiple processing modules and models |
| Per-directory configuration | Configuration is normally centralized; it does not use .htaccess | Can support .htaccess when enabled |
| Reverse proxy use | Commonly deployed as a frontend proxy | Also supports reverse proxying through modules |
| Static file serving | Frequently used for direct static-file delivery | Also serves static files |
| Application integration | Usually proxies to an application runtime or FastCGI service | Can proxy to runtimes or integrate through modules |
Neither server is universally preferable. The choice depends on application requirements, existing configuration, module needs, administrator experience, hosting constraints, and measured performance. NGINX can also run in front of Apache rather than replacing it.
NGINX security and maintenance practices
- Install supported package updates and review security advisories for the deployed version.
- Run
nginx -tbefore every configuration reload. - Expose only required network ports.
- Restrict access to private keys and sensitive configuration files.
- Do not reveal internal services directly when they should be reachable only through the proxy.
- Set request-size and timeout limits according to application requirements.
- Rotate and monitor access and error logs.
- Back up tested configuration before significant changes.
- Apply rate limiting or access controls only after confirming that trusted proxies and client addresses are handled correctly.
- Test certificate renewal and HTTPS redirects before relying on unattended automation.
Is NGINX end of life?
NGINX Open Source is not generally end of life. The project continues to publish source code, documentation, packages, and releases. However, an individual NGINX version, operating-system package, commercial product release, or third-party project that uses the NGINX name may have its own maintenance lifecycle.
Do not confuse the NGINX web server with a particular Kubernetes ingress controller. Lifecycle announcements for an ingress-controller project do not automatically mean that the core NGINX web server has been discontinued. Check the exact product or repository named in an announcement.
Official NGINX documentation and downloads
- NGINX official website
- NGINX Open Source documentation
- NGINX Beginner’s Guide
- NGINX downloads
- Official NGINX Open Source repository
- NGINX administration guide
NGINX FAQs
What is NGINX and why is it used?
NGINX is a web server and proxy server. It is used to serve static content, route requests to application servers, terminate HTTPS connections, cache responses, and balance traffic across multiple backends.
Is NGINX free?
NGINX Open Source is free and open-source software. NGINX Plus is a separate commercial offering with additional features and vendor support.
Why am I seeing the NGINX welcome page?
The welcome page indicates that an NGINX server answered the request, but the request probably matched its default configuration. Verify DNS, server_name, enabled configuration files, and whether NGINX was reloaded after changes.
Can NGINX run on Windows?
NGINX provides a Windows build, but the official documentation describes it as a development version with limitations compared with Unix-based deployments. Linux or another supported Unix-like environment is generally used for production installations.
Does NGINX replace an application server?
Not usually. NGINX can serve static files and route requests, but application code commonly runs in a separate runtime or application server. NGINX forwards dynamic requests to that service through HTTP, FastCGI, uWSGI, SCGI, or another supported protocol.
NGINX tutorial QA checklist
- Confirm installation commands match the stated Linux distribution and package source.
- Verify every
server_name, document root, upstream address, and certificate path before publishing examples. - Run
nginx -tbefore demonstrating a reload or restart. - Check whether
proxy_passtrailing-slash behavior matches the intended upstream URI. - Confirm reverse-proxy examples preserve the required host, client-address, and protocol headers.
- Do not describe a Kubernetes ingress-controller retirement as the end of the NGINX web server.
- Keep NGINX Open Source and the commercial NGINX Plus product clearly distinguished.
- Verify troubleshooting advice directs readers to both the NGINX error log and upstream application logs.
TutorialKart.com