How To Install Nginx on Fedora 44

Install Nginx on Fedora 44

Running a web server on Linux does not have to be complicated. If you want to install Nginx on Fedora 44, the entire process from a fresh system to a working HTTPS site takes less than 30 minutes with the right steps. Nginx is a battle-tested, high-performance web server that powers a massive chunk of the internet, from personal blogs to enterprise applications. This guide walks you through the complete Nginx on Fedora 44 setup: installation, firewall configuration, SELinux labeling, server blocks, SSL certificates, and troubleshooting. Every step includes a clear explanation of why it matters, not just what to type.

Prerequisites

Before you start, confirm you have the following ready:

  • Fedora 44 installed (workstation or server edition)
  • A user account with sudo privileges or direct root access
  • An active internet connection for downloading packages
  • A terminal emulator open and ready
  • (Optional) A registered domain name if you plan to create a server block and add SSL

You do not need to add any third-party repository. Fedora 44 ships Nginx version 1.30.1-1.fc44.x86_64 in its default repositories, so the standard DNF package manager handles everything.

What Is Nginx and Why Use It on Fedora 44?

Nginx (pronounced “engine-x”) is an open-source, event-driven web server. Unlike older web servers that spawn a new process or thread for each incoming connection, Nginx handles thousands of concurrent requests using an asynchronous, non-blocking architecture. That design keeps memory usage low even under heavy traffic.

Nginx has several use cases beyond just serving static HTML files:

  • Static site hosting for fast content delivery
  • Reverse proxy for forwarding requests to backend apps like Node.js, Python, or PHP-FPM
  • Load balancer for distributing traffic across multiple application servers
  • HTTP cache for reducing backend load on high-traffic sites

Fedora 44 is a cutting-edge RPM-based distribution that follows a rapid release cycle. Because Fedora ships a current, maintained Nginx build in its default repos, you get security patches through the same dnf upgrade workflow you use for everything else on the system. There is no need to maintain a separate upstream repo or watch for version conflicts.

Step 1: Update Your Fedora 44 System

Always refresh your package metadata before installing anything on Fedora. This step forces DNF to pull the latest package lists from all enabled repositories before resolving dependencies.

sudo dnf upgrade --refresh

Why this matters: Without --refresh, DNF may resolve the install against stale cached metadata. On Fedora’s fast release cycle, package metadata can go out of date quickly, and installing against old dependency information causes version mismatches that are annoying to debug later.

Wait for the upgrade to complete, then confirm your system is current before moving on.

Step 2: Install Nginx on Fedora 44 Using DNF

Now install the Nginx package directly from Fedora’s default repositories:

sudo dnf install nginx

DNF resolves all required dependencies and installs the package in one step. When prompted, type y to confirm the transaction.

Verify the Installation

After installation finishes, confirm the exact package version that was installed:

rpm -q nginx

Expected output:

nginx-1.30.1-1.fc44.x86_64

Why verify the version? Confirming the build before you proceed saves debugging time. If a partial install or dependency issue occurred silently, this command shows it immediately.

Confirm the Nginx System User

The Fedora Nginx package creates a dedicated nginx system user during installation. Verify that Nginx is configured to run its worker processes under that non-privileged account:

grep -E '^user[[:space:]]+nginx;' /etc/nginx/nginx.conf

Expected output:

user nginx;

Why this matters: Running worker processes as the nginx user limits what an attacker can do if they ever exploit a vulnerability in the server. The nginx account has no login shell and no write access to the web root, which keeps the blast radius small.

Step 3: Enable and Start the Nginx Service

Fedora installs Nginx in a stopped, disabled state. You need to enable it so it starts automatically on every reboot, and start it now for the current session.

sudo systemctl enable --now nginx

The --now flag combines two operations into one command. It both registers Nginx to start at boot and starts the service immediately. Many tutorials separate these into two commands and people forget the second one, leaving the service enabled but not running.

Confirm the Service Is Running

Run these two checks to confirm the service state:

systemctl is-enabled nginx
systemctl is-active nginx

Expected output:

enabled
active

Test the Local Response

Send a quick HTTP request from the same machine to confirm Nginx is actually serving content:

curl -fsSI http://127.0.0.1/

Expected output:

HTTP/1.1 200 OK
Server: nginx/1.30.1
Content-Type: text/html

A 200 OK response confirms Nginx is listening on port 80 and serving the default page. You can also open http://localhost in a browser if you are on a desktop install.

Step 4: Open HTTP and HTTPS Ports in Firewalld

Fedora ships with firewalld active and blocking all inbound connections by default. Without explicitly opening ports 80 and 443, no external traffic can reach Nginx even though the service is running.

Add the HTTP and HTTPS service rules and make them permanent:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Why use --permanent? Rules added without this flag exist only in the current runtime. A system reboot or firewalld restart removes them. The --permanent flag writes the rule to the persistent firewalld configuration file on disk.

Why --reload after? The permanent config and the runtime config are separate. After writing permanent rules, you must reload firewalld to push those changes into the active runtime. Without a reload, your ports stay closed until the next reboot.

Why use service names instead of port numbers? Fedora’s firewalld service definitions handle both IPv4 and IPv6 traffic automatically. Specifying --add-service=http is cleaner and less error-prone than specifying --add-port=80/tcp.

Confirm the Rules Are Active

firewall-cmd --query-service=http
firewall-cmd --query-service=https

Expected output for each:

yes

Step 5: Understand Nginx’s Configuration Layout on Fedora 44

Before you create your own site configuration, it helps to know where things live. The Fedora Nginx package uses a clean layout that differs from what you see on Debian and Ubuntu.

Key file paths:

  • /etc/nginx/nginx.conf – The main configuration file. It sets global options like the worker user, worker process count, and error log path. It also contains an include directive that loads all .conf files from the directory below.
  • /etc/nginx/conf.d/*.conf – The drop-in directory for individual site configurations. Every file with a .conf extension here gets loaded automatically.
  • /var/log/nginx/access.log – Records all incoming HTTP requests.
  • /var/log/nginx/error.log – Records startup failures, config errors, and runtime problems.
  • /usr/share/nginx/html – The default document root for the packaged welcome page.

Why this matters: Fedora uses a conf.d/ drop-in pattern instead of the sites-available/sites-enabled symlink system used on Debian-based distros. If you follow a Ubuntu-based tutorial on Fedora, the symlink commands will fail silently and your config will never load. Knowing this layout upfront prevents that confusion.

Best practice is to leave /etc/nginx/nginx.conf untouched and create one new .conf file per site inside /etc/nginx/conf.d/.

Step 6: Configure Nginx on Fedora 44 with a Server Block

A server block (called a virtual host in Apache) tells Nginx which domain to listen for and where to find the files to serve. You need one server block per website.

Create the Document Root Directory

Create the directory that will hold your site’s files:

sudo mkdir -p /var/www/example.com/html

Give your current user ownership of the new directory so you can edit files without using sudo every time:

sudo chown -R $USER:$USER /var/www/example.com

Set permissions so Nginx can read the directory contents:

sudo chmod -R 755 /var/www/example.com

Why 755 and not 777? The 755 permission gives the owner full access and grants read and execute access to everyone else, including the nginx process. The 777 permission grants write access to all users, including the nginx account, which creates a security risk. Never set chmod -R 777 on a web root.

Set the SELinux File Context (Fedora-Specific and Critical)

This step is the one most tutorials skip, and it is the most common reason people hit a 403 Forbidden error on Fedora. SELinux is enforcing by default on Fedora 44. Even if your file permissions look correct, Nginx cannot read files in a custom directory unless that directory carries the right SELinux label.

Install the SELinux management tools if semanage is not already available:

sudo dnf install policycoreutils-python-utils

Add the correct SELinux file context rule for your custom web root:

sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/example.com(/.*)?"

Apply the label to all existing files and subdirectories:

sudo restorecon -Rv /var/www/example.com

Verify the label was applied correctly:

ls -Zd /var/www/example.com/html

Expected output:

unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/example.com/html

The critical part is httpd_sys_content_t. That label tells SELinux that Nginx’s httpd_t process domain is allowed to read files in this directory.

Create a Test Page

Create a simple HTML file to confirm the server block works:

nano /var/www/example.com/html/index.html

Add this content (replace example.com with your actual domain):

<!DOCTYPE html>
<html>
<head>
  <title>Welcome to example.com</title>
</head>
<body>
  <h1>Nginx on Fedora 44 is working!</h1>
</body>
</html>

Save and close the file.

Create the Server Block Configuration File

Create a new configuration file for your domain in the conf.d/ directory:

sudo nano /etc/nginx/conf.d/example.com.conf

Add this server block (replace example.com with your actual domain name):

server {
    listen 80;
    listen [::]:80;

    server_name example.com www.example.com;
    root /var/www/example.com/html;

    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

Why listen [::]:80? This enables IPv6 listening in addition to IPv4. Most modern servers support both protocols, and leaving this out means IPv6 clients cannot reach your site.

Why try_files $uri $uri/ =404? This directive tells Nginx to first look for an exact file match, then try a directory match, then return a clean 404 if neither exists. Without it, Nginx falls back to less predictable behavior that can expose directory listings or serve incorrect content.

Save and close the file.

Step 7: Test and Reload the Nginx Configuration

Never reload Nginx without testing the configuration first. A syntax error in any .conf file will crash the reload and take your site offline.

Run the built-in syntax checker:

sudo nginx -t

Expected output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If the test passes, reload Nginx to activate the new server block:

sudo systemctl reload nginx

Why reload instead of restart? A restart command kills all worker processes immediately, dropping any active connections. A reload sends a signal to the master process, which spawns new workers with the updated configuration while the existing workers finish serving their current requests. This gives you a zero-downtime configuration change.

Step 8: Add Free SSL with Let’s Encrypt and Certbot

HTTP serves content in plaintext. Anyone on the network between your user and your server can read that traffic. HTTPS encrypts the connection, protects user data, and is required for browser trust indicators and search engine ranking signals. Let’s Encrypt provides free, automated SSL certificates through Certbot.

Install Certbot with the Nginx Plugin

sudo dnf install python3-certbot-nginx

Request the Certificate

Run Certbot against your domain. Replace the email and domain values with your own:

sudo certbot --nginx --agree-tos --redirect \
  --email you@example.com \
  -d example.com -d www.example.com

What each flag does:

  • --nginx – Tells Certbot to use the Nginx plugin, which reads your existing server block and writes the TLS configuration automatically
  • --agree-tos – Accepts the Let’s Encrypt Terms of Service without prompting
  • --redirect – Adds an HTTP-to-HTTPS redirect rule to the server block automatically
  • --email – Associates your email with the certificate for expiry notifications

Why is --redirect important? Without it, Certbot installs the certificate but leaves the HTTP listener running in parallel. Users who type your domain without https:// still get an unencrypted connection.

Verify the Automatic Renewal Timer

Fedora’s Certbot package installs a systemd timer that renews certificates before they expire. Let’s Encrypt certificates are valid for 90 days, so automatic renewal is essential.

Check that the timer exists and is enabled:

systemctl list-unit-files "certbot*"

Expected output:

UNIT FILE               STATE    PRESET
certbot-renew.service   static   -
certbot-renew.timer     enabled  enabled

Run a dry run to confirm the entire renewal pipeline works:

sudo certbot renew --dry-run

A successful dry run shows a message confirming the simulated renewal succeeded without errors.

Troubleshooting Common Nginx Issues on Fedora 44

Problem 1: Default Nginx Welcome Page Keeps Showing

Your domain loads but shows the generic Nginx welcome page instead of your custom site.

Cause: The server_name directive in your config file does not match the domain you are requesting, or the DNS record still points to the wrong IP address.

Fix: Check that your server block file contains the correct domain:

grep -R "server_name" /etc/nginx/conf.d/
sudo nginx -t

If the domain is correct but DNS is not yet pointing to the server, use the --resolve option in curl to test locally:

curl --noproxy '*' -fsS --resolve example.com:80:127.0.0.1 http://example.com/

Problem 2: 403 Forbidden Error on a Custom Document Root

You created a custom directory under /var/www/ but Nginx returns a 403 error.

Cause: The SELinux file context on the custom directory is missing or incorrect. This is the most common Nginx issue specific to Fedora. File permissions may look fine, but SELinux enforces its own access rules on top of standard Unix permissions.

Fix: Check the current SELinux label on the directory:

ls -Zd /var/www/example.com/html

If you do not see httpd_sys_content_t in the output, re-run the semanage and restorecon commands from Step 6.

Problem 3: Port 80 or 443 Is Unreachable from Outside

The server is running, but external clients cannot connect to the site.

Cause: The firewall-cmd rules were added without --permanent and were lost after a reboot, or --reload was never run after adding the rules.

Fix: Re-run the firewall configuration from Step 4 and confirm with --query-service:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
firewall-cmd --query-service=http

Problem 4: nginx -t Reports a Syntax Error

You ran nginx -t and got a message like unknown directive or unexpected "}".

Cause: A missing semicolon, unclosed curly brace, or incorrect directive name in one of the .conf files.

Fix: The error output always includes the file path and line number. Open that specific file and look at the line reported:

sudo nginx -t
# Example output: nginx: [emerg] unexpected "}" in /etc/nginx/conf.d/example.com.conf:12
sudo nano /etc/nginx/conf.d/example.com.conf

Check for missing semicolons at the end of directives and make sure every opening { has a matching closing }.

Problem 5: Certbot Fails with “No Valid A Record” Error

Certbot cannot issue the certificate and returns a DNS validation error.

Cause: Your domain’s DNS A record does not yet point to the server’s public IP address, or the DNS change has not propagated yet.

Fix: Verify your domain resolves to the correct IP before running Certbot again:

dig +short example.com

The output should return your server’s public IP address. If DNS is still propagating, wait 10 to 30 minutes and try again.

Useful Nginx Service Management Commands

Once Nginx is running in production, you will use these systemctl commands regularly:

sudo systemctl stop nginx        # Stop the server immediately
sudo systemctl start nginx       # Start the server
sudo systemctl restart nginx     # Full restart (use after binary updates)
sudo systemctl reload nginx      # Zero-downtime config reload
sudo systemctl enable nginx      # Enable auto-start on boot
sudo systemctl disable nginx     # Disable auto-start on boot
sudo tail -f /var/log/nginx/access.log  # Live traffic monitoring
sudo tail -f /var/log/nginx/error.log   # Live error monitoring

Reload vs. restart at a glance:

Command Effect Use When
reload Graceful config update, zero dropped connections After editing .conf files
restart Full process kill and restart After a binary package update
stop/start Immediate halt and cold start Troubleshooting a hung process

The single most important habit here is always running sudo nginx -t before any reload. A config test that takes two seconds prevents a reload that takes your site offline.

r00t is a Linux Systems Administrator and open-source advocate with over ten years of hands-on experience in server infrastructure, system hardening, and performance tuning. Having worked across distributions such as Debian, Arch, RHEL, and Ubuntu, he brings real-world depth to every article published on this blog. r00t writes to bridge the gap between complex sysadmin concepts and practical, everyday application — whether you are configuring your first server or optimizing a production environment. Based in New York, US, he is a firm believer that knowledge, like open-source software, is best when shared freely.

Related Posts