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 nginx
Start and Enable the Service
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
Allow Nginx in UFW Firewall
sudo ufw allow 'Nginx Full'
sudo ufw status
Verify 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 nginx
Start and Enable Nginx
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx
Open 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-all
SELinux 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.com
Create 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 nginx
RHEL/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 nginx
Create a simple test page:
echo "<h1>It works!</h1>" | sudo tee /var/www/example.com/html/index.html
Add 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-fpm
Nginx 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.php
Enable 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.com
Certbot 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.log
Zero-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
Is Nginx better than Apache for high-traffic sites?
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.
How do I create multiple sites (virtual hosts) in Nginx?
Create a separate server block per domain. On Ubuntu/Debian, place files in /etc/nginx/sites-available and symlink to sites-enabled. On RHEL-based distros, add a .conf file under /etc/nginx/conf.d. Test with nginx -t and reload.
What ports should be open for Nginx?
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.
How do I renew Let’s Encrypt certificates automatically?
Certbot installs a systemd timer or cron job for auto-renewal. Verify with sudo systemctl list-timers | grep certbot or run a dry run: sudo certbot renew --dry-run. Certificates renew around 30 days before expiry.
Can Nginx serve as a load balancer?
Yes. Define an upstream block with multiple backend servers and reference it via proxy_pass. Use load-balancing methods like round-robin (default), least_conn, or ip_hash, and add health checks with max_fails and fail_timeout.
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.