Private files: 404 Not Found nxginx

I’ve deployed ERPNext 15 on Ubuntu 22.04.4.

Everything works as expected except from this issue that when I as any user (also System Manager) upload a file into the “File Manager” or anywhere else like attach an image in the description of a support issue the file will upload, but will not be accessible by my user (System Manger) or other logged in users in ERPNext.

If I make the files Public (unchecking Private) the files are available to all users.

I’ve tried troubleshooting for a long time but I’m not able to find the root of the problem.

I’ve made a video to better illustrate the issue:

Here is some of my current settings in ERPNext:




Here is also some of the settings on my server that can give a clue about what I’m doing wrong:

/etc/nginx/sites-available/erpnext-domain-com:

upstream erpnext-domain-com {
    server 127.0.0.1:8000 fail_timeout=0;
}

server {
    listen 80;
    server_name erpnext.domain.com;

    location / {
        proxy_pass http://erpnext-domain-com;
        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;
    }

    location /assets {
        alias /home/frappe/frappe-bench/sites/assets;
        try_files $uri =404;
    }

    location /files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/public/files;
        try_files $uri =404;
    }

    location /private/files {
        internal;
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/private/files;
        try_files $uri =404;
    }

    if ($host = erpnext.domain.com) {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name erpnext.domain.com;

    ssl_certificate /etc/letsencrypt/live/erpnext.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/erpnext.domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://erpnext-domain-com;
        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;
    }

    location /assets {
        alias /home/frappe/frappe-bench/sites/assets;
        try_files $uri =404;
    }

    location /files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/public/files;
        try_files $uri =404;
    }

    location /private/files {
        internal;
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/private/files;
        try_files $uri =404;
    }
}

/home/frappe/frappe-bench/sites/erpnext.domain.com/site_config.json:

{
  "app_logo_url": "/files/logo.svg",
  "db_name": "_c7574a34c0742941",
  "db_password": "hiddendbpassword",
  "developer_mode": 1,
  "db_type": "mariadb",
  "domains": [
    "erpnext.domain.com"
  ],
  "encryption_key": "hiddenencryptionkey",
  "host_name": "https://erpnext.domain.com",
  "use_ssl": 1,
  "log_level": "DEBUG"
}

/etc/letsencrypt/options-ssl-nginx.conf:

ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;

ssl_ciphers "hidden>

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

I’d really appreciate some feedback :pray:

I found the solution!!

This is the updated /etc/nginx/sites-available/erpnext-domain-com:

upstream erpnext-domain-com {
    server 127.0.0.1:8000 fail_timeout=0;
}

server {
    listen 80;
    server_name erpnext.domain.com;

    location / {
        proxy_pass http://erpnext-domain-com;
        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;
    }

    location /assets {
        alias /home/frappe/frappe-bench/sites/assets;
        try_files $uri =404;
    }

    location /files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/public/files;
        try_files $uri =404;
    }

    location /private/files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/private/files;
        try_files $uri =404;
        proxy_pass http://erpnext-domain-com; # Add this line to pass requests to ERPNext
        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;
    }

    if ($host = erpnext.domain.com) {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name erpnext.domain.com;

    ssl_certificate /etc/letsencrypt/live/erpnext.domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/erpnext.domain.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://erpnext-domain-com;
        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;
    }

    location /assets {
        alias /home/frappe/frappe-bench/sites/assets;
        try_files $uri =404;
    }

    location /files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/public/files;
        try_files $uri =404;
    }

    location /private/files {
        alias /home/frappe/frappe-bench/sites/erpnext.domain.com/private/files;
        try_files $uri =404;
        proxy_pass http://erpnext-domain-com; # Add this line to pass requests to ERPNext
        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;
    }
}