Static File Serving¶
Navigator can serve static files directly from the filesystem, bypassing Rails for better performance. This includes assets, images, documents, and any other static content.
Basic Configuration¶
static:
directories:
- path: /assets/
root: public/assets/
cache: 86400
extensions: [css, js, png, jpg, gif, ico]
Directory Mappings¶
Map URL paths to filesystem directories:
static:
directories:
# Rails assets (precompiled)
- path: /assets/
root: public/assets/
cache: 31536000 # 1 year (fingerprinted files)
# Webpack/Vite assets
- path: /packs/
root: public/packs/
cache: 31536000
# User uploads
- path: /uploads/
root: storage/uploads/
cache: 3600 # 1 hour
# Documentation
- path: /docs/
root: public/docs/
cache: 86400 # 1 day
Directory Configuration¶
Field | Type | Required | Description |
---|---|---|---|
path |
string | ✓ | URL path (must start and end with /) |
root |
string | ✓ | Filesystem directory path |
cache |
integer | Cache-Control max-age in seconds |
File Extensions¶
Serve files with specific extensions directly:
static:
extensions: [
# Web assets
css, js, map,
# Images
png, jpg, jpeg, gif, ico, svg, webp,
# Fonts
woff, woff2, ttf, eot, otf,
# Documents
pdf, txt, xml, json,
# Audio/Video
mp3, mp4, webm, ogg
]
Files matching these extensions are served directly regardless of path.
Try Files Behavior¶
Enable nginx-style try_files for better static site support:
static:
try_files:
enabled: true
suffixes: [".html", "index.html", ".htm", ".txt", ".xml", ".json"]
fallback: rails
How Try Files Works¶
- Request comes in:
/about
- Navigator tries in order:
/about
(exact file)/about.html
/about/index.html
/about.htm
/about.txt
/about.xml
/about.json
- If no file found, falls back to Rails
Try Files Configuration¶
Field | Type | Default | Description |
---|---|---|---|
enabled |
boolean | false |
Enable try_files behavior |
suffixes |
array | [] |
File suffixes to try |
fallback |
string | "rails" |
What to do when no file found |
Cache Control¶
Set appropriate cache headers for different content types:
static:
directories:
# Long cache for fingerprinted assets
- path: /assets/
root: public/assets/
cache: 31536000 # 1 year
# Medium cache for images
- path: /images/
root: public/images/
cache: 86400 # 1 day
# Short cache for dynamic content
- path: /api/docs/
root: public/api-docs/
cache: 300 # 5 minutes
# No cache for development
- path: /dev/
root: public/dev/
cache: 0 # Always revalidate
Cache Duration Guidelines¶
Content Type | Duration | Seconds | Use Case |
---|---|---|---|
Immutable assets | 1 year | 31536000 | Fingerprinted files |
Semi-static | 1 week | 604800 | Images, fonts |
Dynamic | 1 hour | 3600 | Generated content |
Real-time | 5 minutes | 300 | API docs |
Development | No cache | 0 | Local development |
MIME Types¶
Navigator automatically detects MIME types based on file extensions:
Extension | MIME Type | Description |
---|---|---|
.html , .htm |
text/html |
HTML documents |
.css |
text/css |
Stylesheets |
.js |
application/javascript |
JavaScript |
.json |
application/json |
JSON data |
.xml |
application/xml |
XML documents |
.png |
image/png |
PNG images |
.jpg , .jpeg |
image/jpeg |
JPEG images |
.gif |
image/gif |
GIF images |
.svg |
image/svg+xml |
SVG images |
.ico |
image/x-icon |
Icons |
.pdf |
application/pdf |
PDF documents |
.woff |
font/woff |
Web fonts |
.woff2 |
font/woff2 |
Web fonts v2 |
Performance Optimization¶
1. Serve Assets Directly¶
# Instead of letting Rails serve assets
static:
directories:
- path: /assets/
root: public/assets/
cache: 31536000
extensions: [css, js, png, jpg, gif]
applications:
global_env:
RAILS_SERVE_STATIC_FILES: "false" # Let Navigator handle it
2. Optimize Directory Structure¶
# Good: Organized by type
public/
├── assets/ # Compiled assets
├── images/ # Static images
├── fonts/ # Web fonts
└── docs/ # Documentation
# Avoid: Mixed content
public/
├── style.css # Mixed with HTML
├── app.js
├── logo.png
└── about.html
3. Use Compression¶
# Pre-compress static files
gzip -k -9 public/assets/*.css
gzip -k -9 public/assets/*.js
brotli -k -9 public/assets/*.css
brotli -k -9 public/assets/*.js
Navigator will serve pre-compressed files when available.
Common Patterns¶
Rails Application with Assets¶
static:
directories:
# Precompiled Rails assets
- path: /assets/
root: public/assets/
cache: 31536000
# Webpack packs (if using Webpacker)
- path: /packs/
root: public/packs/
cache: 31536000
extensions: [css, js, png, jpg, gif, ico, woff, woff2]
# Enable try_files for public pages
try_files:
enabled: true
suffixes: ["index.html", ".html"]
fallback: rails
applications:
global_env:
RAILS_SERVE_STATIC_FILES: "false"
Static Site with Rails API¶
static:
directories:
# Static site files
- path: /
root: public/dist/
cache: 3600
# Assets with long cache
- path: /assets/
root: public/dist/assets/
cache: 31536000
try_files:
enabled: true
suffixes: ["index.html", "/index.html"]
fallback: rails
applications:
tenants:
# API only handles /api/ paths
- name: api
path: /api/
Multi-Tenant with Shared Assets¶
static:
directories:
# Shared assets for all tenants
- path: /shared/
root: public/shared/
cache: 86400
# Tenant-specific assets
- path: /tenant1/assets/
root: storage/tenants/tenant1/assets/
cache: 3600
- path: /tenant2/assets/
root: storage/tenants/tenant2/assets/
cache: 3600
Development vs Production¶
Security Considerations¶
1. Prevent Directory Traversal¶
Navigator automatically prevents ..
path traversal attacks, but ensure your directory structure is secure:
# Safe
static:
directories:
- path: /public/
root: public/files/ # Contained directory
# Potentially unsafe
static:
directories:
- path: /files/
root: / # Root filesystem access
2. Serve Only Intended Files¶
# Use specific extensions
static:
extensions: [css, js, png, jpg] # Only these types
# Avoid serving all files
# extensions: ["*"] # Don't do this
3. Exclude Sensitive Directories¶
static:
directories:
- path: /assets/
root: public/assets/ # OK - public assets
# Avoid
# - path: /config/
# root: config/ # Contains secrets
# - path: /logs/
# root: log/ # Contains sensitive data
Troubleshooting¶
Files Not Being Served¶
-
Check file exists:
-
Verify path mapping:
-
Test directly:
Wrong MIME Type¶
Navigator uses file extensions for MIME type detection. Ensure files have correct extensions:
# Correct
app.js → application/javascript
style.css → text/css
image.png → image/png
# Problematic
app.js.txt → text/plain (wrong!)
Cache Issues¶
-
Check cache headers:
-
Force refresh:
-
Clear browser cache or use incognito mode
Permission Errors¶
# Ensure Navigator can read files
chmod 644 public/assets/*
chmod 755 public/assets/
# Check ownership
ls -la public/assets/
Monitoring¶
Check Static File Serving¶
# Monitor static file requests
grep "static" /var/log/navigator.log
# Count static vs dynamic requests
grep -c "static" /var/log/navigator.log
grep -c "proxy" /var/log/navigator.log
Performance Testing¶
# Test static file performance
ab -n 1000 -c 10 http://localhost:3000/assets/application.css
# Compare with Rails serving
ab -n 1000 -c 10 http://localhost:3000/non-static-path
Migration from nginx¶
Migrate nginx static file configurations:
# nginx
location /assets/ {
root /var/www/app/public;
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(css|js|png|jpg)$ {
root /var/www/app/public;
expires 1w;
}
Becomes:
# Navigator
static:
directories:
- path: /assets/
root: /var/www/app/public/assets/
cache: 31536000 # 1 year
extensions: [css, js, png, jpg]
# 1 week cache applied to all extensions