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¶
server:
listen: 3000
static:
public_dir: "./public"
allowed_extensions: [css, js, png, jpg, gif, ico]
try_files: [index.html, .html, .htm]
cache_control:
overrides:
- path: /assets/
max_age: 24h
Public Directory¶
Navigator serves static files from a configured public directory:
All static files are served from this single directory. Navigator maps URL paths directly to files within this directory.
Public Directory Configuration¶
Field | Type | Default | Description |
---|---|---|---|
public_dir |
string | "./public" |
Directory path for static files |
Examples:
- URL /assets/app.css
→ File public/assets/app.css
- URL /images/logo.png
→ File public/images/logo.png
- URL /favicon.ico
→ File public/favicon.ico
File Extensions¶
Optionally restrict which file extensions Navigator will serve:
server:
static:
allowed_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
]
When allowed_extensions
is specified, only files with these extensions will be served. If omitted, all file types are allowed.
Try Files Behavior¶
Enable nginx-style try_files for better static site support:
How Try Files Works¶
When try_files
is configured, Navigator attempts to find files with different extensions:
- Request comes in:
/about
- Navigator tries in order:
/about
(exact file)/about.html
/about/index.html
/about.htm
- If no file found, falls back to the Rails application
Try Files Configuration¶
Field | Type | Default | Description |
---|---|---|---|
try_files |
array | [] |
File suffixes to try (empty = disabled) |
Examples:
- try_files: [".html"]
- Try .html
extension
- try_files: ["index.html", ".html"]
- Try index.html first, then .html
- try_files: []
- Disabled (exact path match only)
Cache Control¶
Set appropriate cache headers for different paths:
server:
static:
cache_control:
overrides:
# Long cache for fingerprinted assets
- path: /assets/
max_age: 8760h # 1 year (365 days)
# Medium cache for images
- path: /images/
max_age: 24h # 1 day
# Short cache for dynamic content
- path: /docs/
max_age: 5m # 5 minutes
# No cache for development
- path: /dev/
max_age: 0s # Always revalidate
Cache Duration Guidelines¶
Content Type | Duration | Format | Use Case |
---|---|---|---|
Immutable assets | 1 year | 8760h |
Fingerprinted files |
Semi-static | 1 week | 168h |
Images, fonts |
Dynamic | 1 hour | 1h |
Generated content |
Real-time | 5 minutes | 5m |
API docs |
Development | No cache | 0s |
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
server:
static:
public_dir: "./public"
allowed_extensions: [css, js, png, jpg, gif]
cache_control:
overrides:
- path: /assets/
max_age: 8760h # 1 year
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¶
server:
listen: 3000
static:
public_dir: "./public"
allowed_extensions: [css, js, png, jpg, gif, ico, woff, woff2]
try_files: ["index.html", ".html"]
cache_control:
overrides:
- path: /assets/
max_age: 8760h # 1 year
- path: /packs/
max_age: 8760h # 1 year
applications:
global_env:
RAILS_SERVE_STATIC_FILES: "false"
Static Site with Rails API¶
server:
static:
public_dir: "./public/dist"
try_files: ["index.html", "/index.html"]
cache_control:
overrides:
- path: /
max_age: 1h
- path: /assets/
max_age: 8760h # 1 year
applications:
tenants:
# API only handles /api/ paths
- name: api
path: /api/
Multi-Tenant with Shared Assets¶
server:
static:
public_dir: "./public"
cache_control:
overrides:
# Shared assets for all tenants
- path: /shared/
max_age: 24h
# Tenant-specific assets
- path: /tenant1/assets/
max_age: 1h
- path: /tenant2/assets/
max_age: 1h
Development vs Production¶
Security Considerations¶
1. Prevent Directory Traversal¶
Navigator automatically prevents ..
path traversal attacks, but ensure your directory structure is secure:
# Safe
server:
static:
public_dir: public/ # Contained directory
# Potentially unsafe
server:
static:
public_dir: / # Root filesystem access (avoid!)
2. Serve Only Intended Files¶
# Use specific extensions
server:
static:
allowed_extensions: [css, js, png, jpg] # Only these types
# Or omit to allow all files (use with caution)
server:
static:
# allowed_extensions not specified = all files allowed
3. Exclude Sensitive Directories¶
# Safe - only serve from public directory
server:
static:
public_dir: public/ # Only files in public/ are accessible
# Ensure sensitive files are outside public_dir:
# - config/ (contains secrets)
# - log/ (contains sensitive data)
# - db/ (database files)
Troubleshooting¶
Files Not Being Served¶
-
Check file exists:
-
Verify public directory:
-
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
server:
static:
public_dir: /var/www/app/public
allowed_extensions: [css, js, png, jpg]
cache_control:
overrides:
- path: /assets/
max_age: 8760h # 1 year