To set up Nginx on a Linux server, update your packages, install Nginx from your distro’s repository, allow HTTP/HTTPS in your firewall, start and enable the service, create a server block for your domain, test the configuration, reload Nginx, and add free TLS with Let’s Encrypt for HTTPS. Steps vary slightly by distribution.
In this guide, you’ll learn how to setup Nginx on a Linux server from scratch—covering installation, firewall rules, server blocks, SSL, reverse proxy, and essential optimizations. Whether you’re on Ubuntu, Debian, CentOS, AlmaLinux, or openSUSE, follow along for a clean, secure, and high‑performance Nginx configuration.
Prerequisites and What You’ll Need
- A Linux server (Ubuntu/Debian, CentOS/AlmaLinux/RHEL, openSUSE, or Amazon Linux)
- Root or sudo access
- A domain name (optional but recommended for HTTPS)
- Basic terminal familiarity
- Open ports 80 (HTTP) and 443 (HTTPS)
Install Nginx on Linux (All Major Distros)
Ubuntu/Debian
sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx --no-pager
RHEL/CentOS/AlmaLinux/Amazon Linux
# RHEL/AlmaLinux/Rocky (EPEL may be needed on some versions)
sudo dnf install -y nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx --no-pager
# CentOS 7 (legacy)
sudo yum install -y epel-release
sudo yum install -y nginx
sudo systemctl enable --now nginx
# Amazon Linux 2
sudo amazon-linux-extras install -y nginx1
sudo systemctl enable --now nginx
openSUSE
sudo zypper refresh
sudo zypper install -y nginx
sudo systemctl enable --now nginx
Allow HTTP/HTTPS in the Firewall (and SELinux)
UFW (Ubuntu/Debian)
sudo ufw allow 'Nginx Full' # opens 80 and 443
sudo ufw status
firewalld (RHEL/CentOS/AlmaLinux/Fedora)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
SELinux (if enforcing)
If SELinux is enforcing and you proxy to upstream apps, allow network connections:
sudo setsebool -P httpd_can_network_connect 1
Nginx Directory Structure and Config Basics
- Main configuration:
/etc/nginx/nginx.conf - Extra configs:
/etc/nginx/conf.d/*.conf(all distros) - Debian-style server blocks:
/etc/nginx/sites-available/, symlink tosites-enabled/ - Default web root:
/var/www/html - Logs:
/var/log/nginx/access.log,/var/log/nginx/error.log
Always validate changes with nginx -t and reload the service. This prevents downtime from syntax errors.
Create a Server Block (Virtual Host) for Your Domain
Below is a simple server block for demo.example.com serving static files. Adjust paths and domain as needed.
sudo mkdir -p /var/www/demo.example.com/html
sudo chown -R $USER:$USER /var/www/demo.example.com/html
echo "<h1>Hello from Nginx on Linux!</h1>" | sudo tee /var/www/demo.example.com/html/index.html
Debian/Ubuntu layout:
sudo nano /etc/nginx/sites-available/demo.example.com
server {
listen 80;
listen [::]:80;
server_name demo.example.com;
root /var/www/demo.example.com/html;
index index.html;
access_log /var/log/nginx/demo_access.log;
error_log /var/log/nginx/demo_error.log;
location / {
try_files $uri $uri/ =404;
}
}
sudo ln -s /etc/nginx/sites-available/demo.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
RHEL/CentOS/AlmaLinux layout:
sudo nano /etc/nginx/conf.d/demo.example.com.conf
server {
listen 80;
server_name demo.example.com;
root /var/www/demo.example.com/html;
index index.html;
access_log /var/log/nginx/demo_access.log;
error_log /var/log/nginx/demo_error.log;
location / {
try_files $uri $uri/ =404;
}
}
sudo nginx -t
sudo systemctl reload nginx
Add Free HTTPS with Let’s Encrypt (Certbot)
Use Certbot’s Nginx plugin to request and auto‑configure certificates. Ensure DNS for your domain points to your server’s IP and port 80 is open.
Install Certbot
# Ubuntu/Debian (snap recommended)
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
# RHEL/AlmaLinux/CentOS
sudo dnf install -y certbot python3-certbot-nginx
# openSUSE
sudo zypper install -y certbot python3-certbot-nginx
Obtain and Install Certificates
sudo certbot --nginx -d demo.example.com
# Choose to redirect HTTP to HTTPS when prompted
Certbot sets up auto‑renewal via systemd or cron. Test renewal with:
sudo certbot renew --dry-run
Use Nginx as a Reverse Proxy (Node.js/Python/PHP-FPM)
To serve an application listening on 127.0.0.1:3000, configure Nginx as a reverse proxy with proper headers and WebSocket support:
server {
listen 80;
server_name app.example.com;
# Optional: large uploads
client_max_body_size 20m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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;
# WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
On SELinux systems, enable network connections as noted earlier. For PHP apps, use fastcgi_pass to PHP‑FPM (e.g., unix:/run/php/php8.2-fpm.sock).
Performance Tuning Essentials
- Scale workers automatically and raise connections for busy sites.
- Compress assets (gzip) and cache static files aggressively.
- Disable version tokens in responses.
- Use HTTP/2 by default for TLS (Certbot enables it on many setups).
# /etc/nginx/nginx.conf (http block or include a conf.d/tuning.conf)
worker_processes auto;
events { worker_connections 4096; }
http {
server_tokens off;
# Gzip
gzip on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types text/plain text/css application/javascript application/json application/xml image/svg+xml;
# Cache static assets (adjust paths/locations)
map $sent_http_content_type $expires {
default off;
~image/ 30d;
~font/ 30d;
~text/css 7d;
~application/javascript 7d;
}
# Example static caching location
# location ~* \.(?:css|js|jpg|jpeg|png|gif|svg|ico|webp|woff2?)$ {
# expires $expires;
# add_header Cache-Control "public, immutable";
# }
}
Logging and Monitoring
- Tail logs during debugging:
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log - Analyze traffic with GoAccess:
sudo apt install goaccessthengoaccess /var/log/nginx/access.log --log-format=COMBINED - Integrate with systemd journal:
sudo journalctl -u nginx -e
Common Errors and Quick Fixes
- Port already in use: Another service is on 80/443. Check with
sudo ss -ltnp | grep ':80\|:443'and stop/disable the conflicting service. - Syntax error: Run
sudo nginx -t. Fix the reported line and retry. - 403 Forbidden: Check file permissions/ownership in your
rootpath. Web user (e.g.,www-dataornginx) needs read access. - 502 Bad Gateway: Upstream app is down or wrong
proxy_pass/fastcgi_pass. Verify app’s IP:port/socket and SELinux boolean. - SSL issues: Ensure DNS resolves to your server, port 80 is open, and rerun Certbot. Renewals can be tested with
certbot renew --dry-run.
When to Choose Managed Hosting vs DIY
If you’re deploying business‑critical sites, managed infrastructure can save hours weekly. At YouStable, our SSD/NVMe VPS plans deliver consistent performance, free SSL, and 24×7 expert support. We handle server hardening, firewall, and Nginx optimization so you can focus on your application—not Linux minutiae.
Step-by-Step: Verify and Reload Safely
- Validate:
sudo nginx -t - Reload without downtime:
sudo systemctl reload nginx - Check status:
sudo systemctl status nginx --no-pager - Probe site:
curl -I http://demo.example.comandcurl -I https://demo.example.com
Best Practices Checklist
- Keep Nginx and OS packages updated.
- Use separate server blocks per domain/subdomain.
- Enable HTTPS with HSTS (after confirming TLS works reliably).
- Apply sensible timeouts and request limits to mitigate abuse.
- Back up configs in
/etc/nginx/and use version control. - Monitor logs and set up alerts for spikes or 4xx/5xx errors.
With this step‑by‑step tutorial, you can confidently setup Nginx on a Linux server, enable HTTPS, proxy applications, and optimize performance. If you prefer a faster start, consider a YouStable VPS—prepped for Nginx, security, and scalability from day one.
FAQs: Setup Nginx on Linux Server
How do I check if Nginx is running?
Use systemctl status nginx or sudo ss -ltnp | grep nginx to confirm it’s listening on ports 80/443. You can also visit your server’s IP in a browser to see the default Nginx welcome page.
Where is the Nginx configuration file on Linux?
The main file is /etc/nginx/nginx.conf. Extra configs go in /etc/nginx/conf.d/*.conf. On Ubuntu/Debian, server blocks live in /etc/nginx/sites-available/ with symlinks in sites-enabled/.
How do I reload Nginx after configuration changes?
First run sudo nginx -t to validate syntax. If OK, reload with sudo systemctl reload nginx. A reload applies changes without dropping active connections.
How do I set up multiple websites (virtual hosts)?
Create one server block per domain with its own server_name and root. On Ubuntu/Debian, add files to sites-available/ and enable with symlinks to sites-enabled/. On RHEL-based distros, place each domain in conf.d/ as a separate .conf.
Is Nginx better than Apache?
Both are excellent. Nginx excels at high concurrency, static file delivery, and reverse proxying. Apache offers rich modules and .htaccess flexibility. Many production stacks use Nginx in front of Apache or app servers for best results.