Files
hermes-config/skills/self-hosting/shop-pro-quote/references/nginx-permission-pitfall.md
T
2026-07-12 10:17:17 -04:00

2.1 KiB

Nginx File Permission Pitfall — Prevention Checklist

The bug: New files created in the ShopProQuote project default to 600 (owner-only). Nginx runs as www-data and returns 403 Forbidden when it can't read them. This silently breaks the site.

How it manifests:

  • Pages load but are completely un-styled (CSS files blocked)
  • JS modules fail silently with no console error visible to the user (ES module import fails with 403)
  • Tabs don't work, data doesn't load, buttons do nothing — because the JS module that registers event handlers never executed

Files broken by this in production (2026-06-13):

  • dist/custom.css → site completely un-styled, all Tailwind classes missing
  • shared/debug.js → every JS module that imports from it failed (repair-orders.js, dashboard.js, quote-tab-manager.js, etc.)
  • shared/skeleton.js → skeleton loading states failed

Root cause: The Linux umask for files created by dev tools (workers, write_file tool, touch) produces 600. Nginx needs 644 or better.

Prevention — run after creating ANY new file:

# Fix all JS files with bad permissions
find /mnt/seagate8tb/Websites/ShopProQuote -name "*.js" -perm 600 -exec chmod 644 {} \;

# Fix all CSS files
find /mnt/seagate8tb/Websites/ShopProQuote -name "*.css" -perm 600 -exec chmod 644 {} \;

# Fix all HTML files
find /mnt/seagate8tb/Websites/ShopProQuote -name "*.html" -perm 600 -exec chmod 644 {} \;

Quick diagnostic:

# Check which files are inaccessible to nginx
find /mnt/seagate8tb/Websites/ShopProQuote -perm 600 -name "*.js" -o -name "*.css" -perm 600 | while read f; do
  code=$(curl -sk -o /dev/null -w "%{http_code}" "https://localhost/${f#/mnt/seagate8tb/Websites/ShopProQuote/}")
  echo "$code $f"
done

# Or check nginx error log directly
tail -50 /var/log/nginx/error.log | grep "Permission denied"

When to suspect this: Whenever you create a new shared module, CSS file, or JS utility and suddenly multiple pages break with no obvious JS errors. The browser console may show a failed module import but the root 403 is only visible in nginx logs or curl. Always chmod 644 after creating new project files.