To create Nginx on a Linux server, update your OS packages, install Nginx (apt or dnf/yum), allow HTTP/HTTPS in the firewall, start and enable the service, create a server block (virtual host) for your domain, test the configuration, and reload Nginx.
Optionally enable HTTPS with Let’s Encrypt for free SSL certificates. Want to create Nginx on a Linux server the right way? This guide walks you through installation, configuration, and security on Ubuntu/Debian and RHEL-based distros.
You’ll learn how to set up server blocks, PHP-FPM, reverse proxying for apps, SSL with Let’s Encrypt, performance tuning, and troubleshooting—beginner-friendly yet production-ready.
What You Need Before You Start?
Before you install Nginx, ensure the following prerequisites are in place:
- A Linux server (Ubuntu 22.04/24.04, Debian 12, AlmaLinux/Rocky Linux 9, or CentOS Stream).
- Root or sudo access.
- A registered domain with DNS A/AAAA records pointing to your server’s IP.
- Port 80 (HTTP) and 443 (HTTPS) open in your firewall or cloud security group.
- Basic command-line familiarity and SSH access.
Install Nginx on Ubuntu/Debian
On Debian-based systems, Nginx is available in official repositories and installs in minutes.
Update OS and Install Nginx
sudo apt update && sudo apt -y upgrade
sudo apt -y install nginxStart and Enable the Service
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginxAllow Nginx in UFW Firewall
sudo ufw allow 'Nginx Full'
sudo ufw statusVerify Installation
Visit http://your-domain.com or your server IP. You should see the default Nginx welcome page.
Install Nginx on RHEL/CentOS/AlmaLinux/Rocky
RHEL-family distributions typically use dnf (or yum) and firewalld.
Install Nginx from Repository
sudo dnf -y install epel-release
sudo dnf -y install nginxStart and Enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginxOpen Ports in firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-allSELinux Considerations
If SELinux is enforcing and you change document roots or listen ports, set correct contexts and booleans:
# Example: allow Nginx to connect to upstream services
sudo setsebool -P httpd_can_network_connect 1
# Assign correct context to new webroot
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com(/.*)?"
sudo restorecon -Rv /var/www/example.comCreate Your First Nginx Server Block (Virtual Host)
Server blocks (virtual hosts) let you host multiple sites on one server. Below are examples for Debian/Ubuntu and RHEL-based systems.
Ubuntu/Debian: sites-available and sites-enabled
sudo mkdir -p /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/example.com
sudo chmod -R 755 /var/www/example.com
cat <<'EOF' | sudo tee /etc/nginx/sites-available/example.com
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
access_log /var/log/nginx/example_access.log;
error_log /var/log/nginx/example_error.log;
location / {
try_files $uri $uri/ =404;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxRHEL/AlmaLinux/Rocky: conf.d
sudo mkdir -p /var/www/example.com/html
sudo chown -R nginx:nginx /var/www/example.com
sudo chmod -R 755 /var/www/example.com
cat <<'EOF' | sudo tee /etc/nginx/conf.d/example.com.conf
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.html index.htm;
access_log /var/log/nginx/example_access.log;
error_log /var/log/nginx/example_error.log;
location / {
try_files $uri $uri/ =404;
}
}
EOF
sudo nginx -t && sudo systemctl reload nginxCreate a simple test page:
echo "<h1>It works!</h1>" | sudo tee /var/www/example.com/html/index.htmlAdd PHP Support with PHP-FPM
Nginx serves static files and proxies dynamic requests to PHP-FPM.
Install PHP-FPM
# Ubuntu/Debian
sudo apt -y install php-fpm
# RHEL family
sudo dnf -y install php-fpmNginx Server Block with PHP
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ .php$ {
include snippets/fastcgi-php.conf; # Debian/Ubuntu path
fastcgi_pass unix:/run/php/php8.2-fpm.sock; # adjust PHP version/socket
}
location ~* .(jpg|jpeg|png|gif|svg|css|js|ico)$ {
expires 30d;
access_log off;
}
}Create a phpinfo() file to test:
echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.com/html/info.phpEnable HTTPS with Let’s Encrypt (Certbot)
Free SSL/TLS protects your users and improves SEO. Ensure your DNS points to the server before running Certbot.
Install Certbot and Get Certificates
# Ubuntu/Debian
sudo apt -y install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# RHEL family
sudo dnf -y install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.comCertbot automatically edits your Nginx config, enables HTTPS and HTTP to HTTPS redirects, and sets up automated renewal.
Use Nginx as a Reverse Proxy (Node.js, Python, Ruby)
Nginx excels as a reverse proxy in front of application servers like Node.js, Gunicorn (Python), or Puma (Ruby).
server {
listen 80;
server_name api.example.com;
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;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}When proxying to HTTPS upstreams, add proxy_ssl_server_name on; and ensure upstream certificates validate correctly.
Performance Tuning Essentials
Out-of-the-box defaults are conservative. Tweak wisely and test.
- Workers and connections: set in nginx.conf.
- Compression: enable gzip; consider Brotli if available.
- Static caching: long cache for immutable assets.
- HTTP/2 and TLS: modern ciphers, session reuse.
- Upstream keepalive: improve reverse proxy efficiency.
# /etc/nginx/nginx.conf (excerpt)
worker_processes auto;
events {
worker_connections 1024;
multi_accept on;
}
http {
sendfile on;
keepalive_timeout 65;
server_tokens off;
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml+rss;
gzip_min_length 1024;
# Example: cache static assets aggressively
map $sent_http_content_type $expires {
default off;
~image/ 30d;
~font/ 30d;
~text/css 7d;
~application/javascript 7d;
}
}Security Hardening Checklist
- Hide version:
server_tokens off; - HTTPS everywhere: redirect HTTP to HTTPS, use HSTS if appropriate.
- Security headers: CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy.
- Rate limiting: throttle abusive clients.
- Limit methods and access to sensitive paths.
- Keep Nginx and OpenSSL updated.
# Example headers (in server {} or http {})
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Rate limit: 10 requests/second burst 20 per IP
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
...
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
}
}Logs, Monitoring, and Maintenance
- Logs:
/var/log/nginx/access.logand/var/log/nginx/error.logper site if configured. - Rotate logs: Nginx installs logrotate rules by default; verify in
/etc/logrotate.d/nginx. - Monitor: use
nginx -Vfor build info,systemctl status nginxfor service health, and tools like Netdata, Prometheus, or Uptime Kuma.
# Quick log tail
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.logZero-Downtime Reload and Useful Commands
- Test config:
sudo nginx -t - Reload (no downtime):
sudo systemctl reload nginxorsudo nginx -s reload - Restart:
sudo systemctl restart nginx - View enabled sites (Debian):
ls /etc/nginx/sites-enabled - Check open ports:
ss -tulpn | grep :80|:443
Troubleshooting Common Nginx Errors
- 403 Forbidden: wrong permissions or ownership. Ensure webroot is readable by
www-data(Debian/Ubuntu) ornginx(RHEL). - 404 Not Found: wrong
rootpath or missingtry_files. Confirm file exists in the defined webroot. - 502 Bad Gateway: PHP-FPM or upstream app down or wrong socket/port. Verify PHP-FPM service and
fastcgi_passpath, or upstreamproxy_passtarget. - 413 Request Entity Too Large: increase
client_max_body_sizein server or http block and reload. - SSL Errors: ensure DNS is correct, ports 80/443 open, and Certbot renewal working with
sudo certbot renew --dry-run.
When to Choose Managed Hosting
If you’d rather not manage patches, SSL renewals, monitoring, and scaling yourself, consider a managed VPS or dedicated server. At YouStable, we provide performance-tuned Nginx stacks, free migration, proactive security hardening, and 24/7 expert support—so you can focus on your application while we handle uptime and optimization.
FAQ’s
u003cstrongu003e1. Is Nginx better than Apache for high-traffic sites?u003c/strongu003e
For static files and concurrent connections, Nginx’s event-driven architecture is typically more efficient. Apache is versatile and module-rich. Many production stacks use Nginx as a reverse proxy in front of Apache or app servers to balance strengths.
2. u003cstrongu003eHow do I create multiple sites (virtual hosts) in Nginx?u003c/strongu003e
Create a separate server block per domain. On Ubuntu/Debian, place files in u003ccodeu003e/etc/nginx/sites-availableu003c/codeu003e and symlink to u003ccodeu003esites-enabledu003c/codeu003e. On RHEL-based distros, add a u003ccodeu003e.confu003c/codeu003e file under u003ccodeu003e/etc/nginx/conf.du003c/codeu003e. Test with u003ccodeu003enginx -tu003c/codeu003e and reload.
3. u003cstrongu003eWhat ports should be open for Nginx?u003c/strongu003e
Open TCP 80 for HTTP and 443 for HTTPS. In cloud environments (AWS, GCP, Azure), allow these in security groups or firewall rules. On the server, use UFW or firewalld to permit web traffic.
4. u003cstrongu003eHow do I renew Let’s Encrypt certificates automatically?u003c/strongu003e
Certbot installs a systemd timer or cron job for auto-renewal. Verify with u003ccodeu003esudo systemctl list-timers | grep certbotu003c/codeu003e or run a dry run: u003ccodeu003esudo certbot renew u002du002ddry-runu003c/codeu003e. Certificates renew around 30 days before expiry.
5. u003cstrongu003eCan Nginx serve as a load balancer?u003c/strongu003e
Yes. Define an u003ccodeu003eupstreamu003c/codeu003e block with multiple backend servers and reference it via u003ccodeu003eproxy_passu003c/codeu003e. Use load-balancing methods like round-robin (default), u003ccodeu003eleast_connu003c/codeu003e, or u003ccodeu003eip_hashu003c/codeu003e, and add health checks with u003ccodeu003emax_failsu003c/codeu003e and u003ccodeu003efail_timeoutu003c/codeu003e.
Conclusion
Now you can create Nginx on a Linux server end-to-end: install, configure server blocks, secure with HTTPS, reverse proxy apps, optimize, and keep it hardened. Follow the steps, test with nginx -t, and reload safely. For a worry-free, performance-tuned stack, YouStable’s managed hosting can accelerate your deployment.
