Nginx Setup and Troubleshooting Reference

Table of Contents

  1. Initial Setup Goal
  2. Configuration Files
  3. Creating a Main Personal Webpage
  4. Certbot SSL for a New Domain
  5. Simple HTML Content Example
  6. Troubleshooting 404 and Permission Errors
  7. Logs and Error Diagnosis
  8. Permission Denied (13) Issue
  9. Root Directory Permissions
  10. Why It Worked After Adjusting Permissions

Initial Setup Goal

User:

I’m using my Ubuntu VPS with Nginx and a reverse proxy set up as per these configuration files. I need assistance in creating a main personal webpage accessible via nasserhub.net. I have an application running in the /opt/open-webui folder at https://webui.nasserhub.net/. I want the webpage to be simple, as I plan to add to it later. It should be in a location that is easy for a non-root user to access, develop, and update. Thanks!


Configuration Files

/etc/nginx/nginx.conf

user www-data;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;

events {
  worker_connections 768;
  # multi_accept on;
}

http {

  ##
  # Basic Settings
  ##

  sendfile on;
  tcp_nopush on;
  types_hash_max_size 2048;
  # server_tokens off;

  # server_names_hash_bucket_size 64;
  # server_name_in_redirect off;

  include /etc/nginx/mime.types;
  default_type application/octet-stream;

  ##
  # SSL Settings
  ##

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;

  ##
  # Logging Settings
  ##

  access_log /var/log/nginx/access.log;

  ##
  # Gzip Settings
  ##

  gzip on;

  # gzip_vary on;
  # gzip_proxied any;
  # gzip_comp_level 6;
  # gzip_buffers 16 8k;
  # gzip_http_version 1.1;
  # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  ##
  # Virtual Host Configs
  ##

  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;
}

/etc/nginx/sites-available/webui.conf

server {
    server_name webui.nasserhub.net;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/webui.nasserhub.net/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/webui.nasserhub.net/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = webui.nasserhub.net) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name webui.nasserhub.net;
    return 404; # managed by Certbot
}

We want to add a new site at nasserhub.net while leaving webui.nasserhub.net intact.


Creating a Main Personal Webpage

Step-by-Step Guide

  1. Create a non-root user (already done, user = nasser).

  2. Create a directory for the website (already done at /home/nasser/websites/nasserhub.net/public).

  3. Set ownership and permissions:

    sudo chown -R nasser:www-data /home/nasser/websites/nasserhub.net
    sudo chmod -R 755 /home/nasser/websites/nasserhub.net
  4. Create an Nginx server block for nasserhub.net. Example file:
    /etc/nginx/sites-available/nasserhub.conf:

    server {
        # Redirect HTTP to HTTPS
        listen 80;
        listen [::]:80;
        server_name nasserhub.net www.nasserhub.net;
        return 301 https://nasserhub.net$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name nasserhub.net www.nasserhub.net;
    
        # SSL certificate paths (assuming certs are obtained for nasserhub.net)
        ssl_certificate /etc/letsencrypt/live/nasserhub.net/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/nasserhub.net/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    
        # Root directory for your site
        root /home/nasser/websites/nasserhub.net/public;
        index index.html index.htm;
    
        location / {
            try_files $uri $uri/ =404;
        }
    }
  5. Enable the site:

    sudo ln -s /etc/nginx/sites-available/nasserhub.conf /etc/nginx/sites-enabled/nasserhub.conf
    sudo nginx -t
    sudo systemctl reload nginx
  6. Place or update web files in /home/nasser/websites/nasserhub.net/public/.


Certbot SSL for a New Domain

If you only have certificates for webui.nasserhub.net, you need new ones for nasserhub.net.

  1. Temporary HTTP server block (if needed) for Certbot HTTP challenge:

    server {
        listen 80;
        listen [::]:80;
        server_name nasserhub.net www.nasserhub.net;
    
        root /home/nasser/websites/nasserhub.net/public;
    
        location ~ /.well-known/acme-challenge {
            allow all;
        }
    
        location / {
            try_files $uri $uri/ =404;
        }
    }
  2. Obtain certificate via Certbot:

    sudo certbot --nginx -d nasserhub.net -d www.nasserhub.net

    or

    sudo certbot certonly --webroot \
        -w /home/nasser/websites/nasserhub.net/public \
        -d nasserhub.net -d www.nasserhub.net
  3. Update your nasserhub.conf with the correct SSL paths, then reload.


Simple HTML Content Example

To avoid the default 404 page, create a simple index.html in /home/nasser/websites/nasserhub.net/public:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Welcome to Nasserhub.net</title>
</head>
<body style="margin: 1rem; font-family: Arial, sans-serif;">
  <h1 style="color: #2f4f4f;">I'm Still Alive and Breathing!</h1>
  <p>
    This page is here to let you know the server is online and working. More content coming soon!
  </p>
  <hr>
  <footer style="font-size: 0.9rem; color: #555;">
    &copy; 2025 Nasser Hub
  </footer>
</body>
</html>

Troubleshooting 404 and Permission Errors

If you see 404 Not Found in your browser but you do have an index.html file, it can be:

  1. The Nginx config isn’t loaded or symlinked properly.
  2. The wrong server block is serving the domain (e.g., the default site overshadowing your custom config).
  3. A permission or ownership issue in the file path.

Logs and Error Diagnosis

Use:

sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log

Example:

[crit] 93933#93933: *9054 stat() "/home/nasser/websites/nasserhub.net/public/" failed (13: Permission denied)

means Nginx can’t traverse the directory path.


Permission Denied (13) Issue

If logs say “Permission denied”:


Root Directory Permissions

Example:

/home/nasser => drwxr-x---
/home/nasser/websites => drwxrwxr-x
/home/nasser/websites/nasserhub.net => drwxr-xr-x
/home/nasser/websites/nasserhub.net/public => drwxr-xr-x

Nginx (www-data) can’t read /home/nasser if it’s drwxr-x---. Changing it to drwxr-xr-x (755) fixes that.

sudo chmod 755 /home/nasser

Why It Worked After Adjusting Permissions

By granting “others” execute (and read) permission on /home/nasser (making it 755), you allowed the Nginx worker process (running as www-data) to traverse into the deeper paths (/websites/nasserhub.net/public) and read index.html. This removed the “Permission denied” errors, and your site finally returned a 200 OK response.