Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation
    Live version data by pkgseek.com
    Terminal window
    sudo dnf install -y nginx

    Start and enable at boot:

    Terminal window
    sudo systemctl enable --now nginx

    Verify:

    Terminal window
    sudo systemctl status nginx
    curl -I http://localhost

    Open the firewall ports:

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

    The Nginx configuration directory structure on EL systems is as follows:

    /etc/nginx/
    ├── nginx.conf # Main configuration file
    ├── conf.d/ # Site configuration directory (*.conf auto-loaded)
    │ └── default.conf # Default site configuration
    ├── mime.types # MIME type definitions
    └── fastcgi_params # FastCGI parameters

    Core structure of the main configuration file /etc/nginx/nginx.conf:

    user nginx;
    worker_processes auto;
    error_log /var/log/nginx/error.log;
    pid /run/nginx.pid;
    events {
    worker_connections 1024;
    }
    http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
    '$status $body_bytes_sent "$http_referer" '
    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 65;
    gzip on;
    include /etc/nginx/conf.d/*.conf;
    }

    Each site is configured as a separate file in the /etc/nginx/conf.d/ directory.

    Create /etc/nginx/conf.d/static.example.com.conf:

    server {
    listen 80;
    server_name static.example.com;
    root /var/www/static.example.com;
    index index.html;
    # Static asset caching
    location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff2?)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
    }
    # Deny access to hidden files
    location ~ /\. {
    deny all;
    }
    error_page 404 /404.html;
    }

    Create the website root directory:

    Terminal window
    sudo mkdir -p /var/www/static.example.com
    echo "<h1>Hello from RunEntLinux</h1>" | sudo tee /var/www/static.example.com/index.html

    Test and reload the configuration:

    Terminal window
    sudo nginx -t
    sudo systemctl reload nginx

    Create /etc/nginx/conf.d/app.example.com.conf:

    server {
    listen 80;
    server_name app.example.com;
    location / {
    proxy_pass http://127.0.0.1:8000;
    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;
    }
    }
    upstream app_backend {
    least_conn;
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
    }
    server {
    listen 80;
    server_name app.example.com;
    location / {
    proxy_pass http://app_backend;
    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;
    # Timeout settings
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
    }
    }
    server {
    listen 80;
    server_name ws.example.com;
    location /ws {
    proxy_pass http://127.0.0.1:8000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 86400;
    }
    }

    SSL/TLS Configuration (Let’s Encrypt + Certbot)

    Section titled “SSL/TLS Configuration (Let’s Encrypt + Certbot)”
    1. Install Certbot (it comes from EPEL, so enable EPEL first; a minimal install fails with No match otherwise):

      Terminal window
      sudo dnf install -y epel-release
      sudo dnf install -y certbot python3-certbot-nginx
    2. Obtain a certificate (Certbot will automatically modify the Nginx configuration):

      Terminal window
      sudo certbot --nginx -d app.example.com

      Or obtain a certificate only without modifying the configuration:

      Terminal window
      sudo certbot certonly --nginx -d app.example.com
    3. Manually configure an SSL site. Create /etc/nginx/conf.d/app.example.com.conf:

      server {
      listen 80;
      server_name app.example.com;
      return 301 https://$host$request_uri;
      }
      server {
      # since nginx 1.25.1 the http2 parameter of listen is deprecated; use the standalone directive
      listen 443 ssl;
      http2 on;
      server_name app.example.com;
      ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
      # Secure SSL parameters
      ssl_protocols TLSv1.2 TLSv1.3;
      ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
      ssl_prefer_server_ciphers off;
      # HSTS
      add_header Strict-Transport-Security "max-age=63072000" always;
      # OCSP Stapling
      ssl_stapling on;
      ssl_stapling_verify on;
      location / {
      proxy_pass http://127.0.0.1:8000;
      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;
      }
      }
    4. Set up automatic certificate renewal:

      Terminal window
      sudo systemctl enable --now certbot-renew.timer
      # Or manually test renewal
      sudo certbot renew --dry-run

    On SELinux-enabled systems, Nginx is subject to the httpd_t SELinux policy.

    Nginx cannot read files in a custom directory

    Terminal window
    # View current SELinux context
    ls -laZ /var/www/static.example.com/
    # Set the correct context
    sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/static.example.com(/.*)?"
    sudo restorecon -Rv /var/www/static.example.com/

    Nginx cannot connect to backend services (reverse proxy 502 error)

    Terminal window
    # Allow httpd to make network connections
    sudo setsebool -P httpd_can_network_connect 1

    Nginx cannot connect to a backend on a specific port

    Terminal window
    # View ports httpd is allowed to connect to
    sudo semanage port -l | grep http_port
    # Add a custom port
    sudo semanage port -a -t http_port_t -p tcp 8000

    Nginx cannot bind to a non-standard port

    Terminal window
    # Allow Nginx to listen on a custom port
    sudo semanage port -a -t http_port_t -p tcp 8443
    Terminal window
    # Test configuration syntax
    sudo nginx -t
    # Reload configuration (without interrupting service)
    sudo systemctl reload nginx
    # View active connection status (requires stub_status module)
    # Add the following in a server block:
    # location /nginx_status {
    # stub_status on;
    # allow 127.0.0.1;
    # deny all;
    # }
    curl http://127.0.0.1/nginx_status
    # View error log
    sudo tail -f /var/log/nginx/error.log
    # View access log
    sudo tail -f /var/log/nginx/access.log

    EL 9 and EL 10 package nginx differently, so a single version number is not enough:

    EL 9EL 10
    PackagingAppStream module streams (nginx:1.20/1.22/1.24/1.26)Modularity retired; plain package
    What a default install givesVaries by minor: the CentOS Stream 9 base repo ships 1.20.1, while RHEL/Alma 9.8 already ship 1.26.31.26.3
    Pinning a versiondnf module list nginx, then dnf module enable nginx:<ver> before installingJust install (whatever the repo has)
    Terminal window
    # EL 9: check the current default and available streams first
    sudo dnf module list nginx
    # Enable a specific stream when needed (example: 1.26)
    sudo dnf module enable nginx:1.26 -y
    sudo dnf install -y nginx
    # EL 10: no module streams, install directly
    sudo dnf install -y nginx
    nginx -v # confirm the actual version on both generations

    The “default version” column is a 2026-10 snapshot (AlmaLinux 9.8 = 1.26.3, CentOS Stream 9 base = 1.20.1, EL 10 = 1.26.3); after a minor upgrade, trust dnf module list / nginx -v over this table.

    To pin a specific version, see Package Version Locking.