How To Set up Nginx Server Blocks on Fedora 43

Nginx server blocks enable you to host multiple websites on a single server, similar to Apache’s virtual hosts. This powerful feature allows system administrators and developers to efficiently manage multiple domains without requiring separate physical or virtual machines for each site. Server blocks provide isolation between different websites while maximizing resource utilization on Fedora 43 systems.
Whether you’re running a web hosting service, managing multiple client websites, or simply testing different projects, understanding server blocks is essential. This comprehensive guide walks you through configuring Nginx server blocks on Fedora 43, from initial installation through advanced optimization techniques. You’ll learn proper directory structures, configuration best practices, troubleshooting methods, and security hardening steps to ensure your web server runs smoothly and securely.
Prerequisites and System Requirements
Before diving into Nginx server block configuration, ensure your Fedora 43 system meets these requirements. You’ll need root or sudo access to execute administrative commands throughout this tutorial. Basic familiarity with Linux command-line operations will help you navigate the configuration process more efficiently.
Your server should have at least 1GB of RAM and one CPU core, though these specifications depend on expected traffic volumes. Having registered domain names pointing to your server’s IP address is necessary for production environments, though you can use the hosts file for local testing. Ensure your system has an active internet connection for package installation and updates.
A text editor like nano or vi should be available on your system. Fedora 43 includes these by default, so you’re ready to create and modify configuration files as needed.
Step 1: Installing Nginx on Fedora 43
Updating System Packages
Start by refreshing your system’s package repository information. This ensures you’ll install the latest stable version of Nginx available for Fedora 43:
sudo dnf update -y
Keeping your system updated prevents compatibility issues and ensures you have the latest security patches. The update process may take a few minutes depending on how many packages require updates.
Installing Nginx
Install Nginx using DNF, Fedora’s default package manager:
sudo dnf install nginx -y
The -y flag automatically confirms the installation, streamlining the process. DNF resolves dependencies automatically, installing any required packages alongside Nginx. Verify the installation succeeded by checking the installed version:
nginx -v
This command displays the Nginx version number, confirming successful installation.
Starting and Enabling Nginx Service
Launch the Nginx service and configure it to start automatically at system boot:
sudo systemctl start nginx
sudo systemctl enable nginx
Check that Nginx is running correctly:
sudo systemctl status nginx
A green “active (running)” status indicates Nginx is operational. The service should now respond to web requests on your server.
Step 2: Configuring Firewall for Nginx
Understanding Firewalld on Fedora 43
Fedora 43 uses firewalld as its default firewall management tool. This dynamic firewall daemon provides zone-based network configuration, offering flexibility and security. By default, firewalld blocks incoming connections to most ports, including HTTP and HTTPS.
Opening Required Ports
Allow web traffic through your firewall by enabling HTTP and HTTPS services:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
The --permanent flag ensures these rules persist across system reboots. The reload command applies changes immediately without disrupting existing connections.
Verifying Firewall Configuration
Confirm the firewall rules are active:
sudo firewall-cmd --list-services
You should see both http and https listed among the allowed services. Test Nginx accessibility by visiting your server’s IP address in a web browser. You should see the default Nginx welcome page.
Checking for Conflicting Web Servers
If Apache is installed and running, it may conflict with Nginx since both use port 80. Check for Apache:
sudo systemctl status httpd
If Apache is running, stop and disable it:
sudo systemctl stop httpd
sudo systemctl disable httpd
Step 3: Understanding Nginx Directory Structure
Main Configuration File
Nginx’s primary configuration resides in /etc/nginx/nginx.conf. This file contains global settings organized into contexts: main, events, http, server, and location. Understanding this hierarchy helps you place directives correctly.
The main context contains settings affecting the entire Nginx process. The events context manages connection processing methods. The http context holds directives for web server functionality, including server blocks.
Server Block Configuration Directories
Fedora’s Nginx package uses /etc/nginx/conf.d/ for server block configurations. Any file with a .conf extension in this directory gets automatically included in the main configuration. This approach keeps individual site configurations organized and manageable.
Create configuration files like example.com.conf or mysite.conf in this directory. Each file should contain one complete server block configuration.
Alternative Sites-Available/Sites-Enabled Structure
Many administrators prefer the sites-available/sites-enabled approach borrowed from Apache. This method provides easier site management through symbolic links. Create these directories:
sudo mkdir -p /etc/nginx/sites-available
sudo mkdir -p /etc/nginx/sites-enabled
Edit /etc/nginx/nginx.conf and add this line within the http block:
include /etc/nginx/sites-enabled/*;
Store all site configurations in sites-available, then create symbolic links in sites-enabled for active sites. This allows quick enabling or disabling without editing configuration files.
Document Root Directories
Website files typically reside in /var/www/html/ or /usr/share/nginx/html/. Organizing sites in subdirectories like /var/www/html/example.com/ maintains clarity when managing multiple domains. This structure separates each website’s files, preventing confusion and simplifying backups.
Step 4: Creating Directory Structure for Your Website
Creating Document Root
Establish a directory for your website’s files:
sudo mkdir -p /var/www/html/example.com
The -p flag creates parent directories if they don’t exist. Replace example.com with your actual domain name. Creating domain-specific directories helps organize multiple sites efficiently.
Creating Sample HTML File
Generate a simple test page to verify your server block configuration:
sudo nano /var/www/html/example.com/index.html
Add this HTML content:
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Example.com</title>
</head>
<body>
<h1>Success! Server block is working.</h1>
<p>This is the example.com website.</p>
</body>
</html>
Save and close the file. This page confirms Nginx is serving content from the correct directory.
Setting Proper Permissions
Configure ownership and permissions to allow Nginx to read and serve files:
sudo chown -R nginx:nginx /var/www/html/example.com
sudo chmod -R 755 /var/www/html/example.com
The nginx user and group should own website files. The 755 permission grants read and execute access to the web server while maintaining security. Incorrect permissions cause 403 Forbidden errors, preventing content delivery.
Step 5: Creating Your First Server Block
Creating Configuration File
Navigate to the configuration directory and create your server block file:
sudo nano /etc/nginx/conf.d/example.com.conf
Using descriptive filenames helps identify configurations quickly, especially when managing many sites.
Basic Server Block Configuration
Add this complete server block configuration:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/html/example.com;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
The listen directives specify which ports Nginx monitors for incoming connections. Including both IPv4 and IPv6 ensures compatibility with all client types. The server_name directive defines which domain names this server block handles, supporting multiple domains or subdomains separated by spaces.
Location Block Configuration
The location directive determines how Nginx processes different URI patterns. The try_files directive attempts to serve the requested URI as a file first, then as a directory, and finally returns a 404 error if neither exists. This efficient file serving method handles most static content scenarios.
Location blocks can contain additional directives for specific URL patterns. You might configure separate locations for static assets, API endpoints, or application routes.
Error Page Configuration
Custom error pages improve user experience when issues occur. Add these directives within your server block:
error_page 404 /404.html;
location = /404.html {
internal;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
internal;
}
The internal directive prevents direct access to error page files, allowing them only through internal redirects.
Step 6: Creating Multiple Server Blocks
Setting Up Second Website
Create infrastructure for an additional domain:
sudo mkdir -p /var/www/html/secondsite.com
sudo nano /var/www/html/secondsite.com/index.html
Add distinguishing content so you can verify which server block is responding:
<!DOCTYPE html>
<html>
<head>
<title>Second Site</title>
</head>
<body>
<h1>This is the second website</h1>
</body>
</html>
Set appropriate permissions:
sudo chown -R nginx:nginx /var/www/html/secondsite.com
sudo chmod -R 755 /var/www/html/secondsite.com
Server Block for Second Domain
Create a separate configuration file:
sudo nano /etc/nginx/conf.d/secondsite.com.conf
Add this server block:
server {
listen 80;
listen [::]:80;
server_name secondsite.com www.secondsite.com;
root /var/www/html/secondsite.com;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/secondsite.com.access.log;
error_log /var/log/nginx/secondsite.com.error.log;
}
Nginx uses the server_name directive to route requests to the correct server block. When a request arrives, Nginx compares the Host header against all server_name values to find the matching configuration.
Default Server Block
Configure a catch-all server block for requests without matching server names:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
The default_server parameter designates this as the fallback for unmatched requests. Returning 444 closes the connection without sending a response, protecting against domain-scanning attacks.
Step 7: Testing and Activating Server Blocks
Testing Nginx Configuration
Always validate configuration syntax before reloading Nginx:
sudo nginx -t
This command performs a syntax check and reports errors with file names and line numbers. A successful test shows “syntax is ok” and “test is successful” messages. Never skip this step because configuration errors can prevent Nginx from starting.
Reloading Nginx
Apply configuration changes with a graceful reload:
sudo systemctl reload nginx
Reloading preserves active connections while applying new settings. Use restart only when reload fails or after major configuration changes:
sudo systemctl restart nginx
Verify the service remains active:
sudo systemctl status nginx
Testing with Hosts File (Local Testing)
For testing before DNS propagation, edit your local hosts file. On Linux systems:
sudo nano /etc/hosts
Add these entries, replacing SERVER_IP with your actual server IP:
SERVER_IP example.com www.example.com
SERVER_IP secondsite.com www.secondsite.com
This directs your local machine to resolve these domains to your test server.
Verifying Live Domains
Open a web browser and navigate to your domain. You should see your custom HTML content. Use curl for command-line verification:
curl -I http://example.com
This displays response headers, confirming successful server responses. Check that the server returns an HTTP 200 OK status.
Step 8: Advanced Server Block Configurations
Adding SSL/TLS Support
Secure your websites with HTTPS encryption. After obtaining SSL certificates from Let’s Encrypt or another provider, configure HTTPS:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
root /var/www/html/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
HTTP to HTTPS Redirect
Force encrypted connections by redirecting HTTP traffic:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
The 301 status code indicates a permanent redirect, helping search engines update their indexes.
PHP Processing Configuration
For dynamic PHP applications, configure FastCGI processing:
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Ensure PHP-FPM is installed and running. This configuration handles PHP file execution through the FastCGI protocol.
Access Restrictions
Limit access to specific IP addresses or networks:
location /admin {
allow 192.168.1.0/24;
deny all;
try_files $uri $uri/ =404;
}
This allows access from the 192.168.1.0/24 subnet while blocking all other addresses.
Step 9: Optimizing Server Block Performance
Enabling Gzip Compression
Reduce bandwidth usage and improve load times with compression:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
Gzip compression significantly decreases file transfer sizes for text-based resources. A compression level of 6 balances CPU usage with file size reduction.
Browser Caching Headers
Configure caching for static assets:
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
This instructs browsers to cache images, stylesheets, and scripts for 30 days, reducing server requests.
Client Body Size Limits
Adjust upload size restrictions based on your needs:
client_max_body_size 100M;
This allows file uploads up to 100 megabytes. Place this directive in the http, server, or location context depending on scope requirements.
Connection and Timeout Settings
Optimize connection handling for your traffic patterns:
keepalive_timeout 65;
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
These values balance resource efficiency with user experience. Adjust them based on your specific workload characteristics.
Troubleshooting Common Issues
Server Block Not Working
If your server block doesn’t respond correctly, verify configuration syntax first. Check that configuration files have the .conf extension and reside in the correct directory. Confirm the include directive in nginx.conf references your configuration location.
DNS propagation delays can take up to 48 hours. Use the hosts file method for immediate testing. Check firewall rules and ensure SELinux isn’t blocking connections.
403 Forbidden Errors
Permission problems commonly cause 403 errors. Verify file ownership matches the nginx user:
ls -la /var/www/html/example.com
Ensure the nginx.conf user directive specifies the correct user. Check that index files exist in the document root. On Fedora, SELinux contexts matter:
sudo chcon -R -t httpd_sys_content_t /var/www/html/example.com
This sets appropriate SELinux contexts for web content.
502 Bad Gateway
This error indicates backend communication failures. For PHP sites, verify PHP-FPM is running:
sudo systemctl status php-fpm
Check socket paths in both Nginx and PHP-FPM configurations match. Review error logs for specific failure details.
Port Already in Use
Identify processes using port 80:
sudo ss -tlnp | grep :80
If Apache or another web server is running, stop it before starting Nginx. Only one service can bind to port 80 simultaneously.
Server Name Not Matching
With many server names, increase the hash bucket size. Add this to the http context in nginx.conf:
server_names_hash_bucket_size 64;
Restart Nginx after making this change.
Security Best Practices
Hiding Nginx Version
Prevent version disclosure to potential attackers:
server_tokens off;
Place this in the http context of nginx.conf to apply globally.
Restricting Access to Hidden Files
Block access to sensitive configuration files:
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
This prevents access to files beginning with a dot, including .htaccess and .git files.
Rate Limiting
Protect against brute-force attacks and abuse:
limit_req_zone $binary_remote_addr zone=limitbyaddr:10m rate=10r/s;
server {
limit_req zone=limitbyaddr burst=20 nodelay;
}
This limits clients to 10 requests per second with a burst allowance of 20.
Security Headers
Add protective HTTP headers:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
These headers help defend against clickjacking, MIME sniffing, and XSS attacks.
Maintaining and Managing Server Blocks
Enabling and Disabling Sites
Using the sites-available/sites-enabled structure simplifies site management. Enable a site by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
Disable a site by removing the symbolic link:
sudo rm /etc/nginx/sites-enabled/example.com.conf
This approach avoids deleting configurations, allowing quick reactivation.
Log File Locations
Monitor access and error logs for troubleshooting and security auditing. Default logs reside in /var/log/nginx/. Configure per-site logs as shown in earlier examples. Review logs regularly:
sudo tail -f /var/log/nginx/example.com.access.log
Regular Maintenance Tasks
Keep Nginx updated with security patches:
sudo dnf update nginx
Implement log rotation to prevent disk space exhaustion. Fedora includes logrotate configuration for Nginx by default. Back up configuration files before making changes:
sudo cp /etc/nginx/conf.d/example.com.conf /etc/nginx/conf.d/example.com.conf.backup
Congratulations! You have successfully set up Nginx Virtual Host. Thanks for using this tutorial to configure Nginx server blocks on Fedora 42 Linux system. For additional help or useful information, we recommend you check the official Nginx website.