Application Configuration¶
The applications
section defines how Navigator manages web applications across different frameworks, including routing, environment variables, and tenant configurations.
Basic Structure¶
applications:
# Framework-specific configuration
framework:
runtime_executable: ruby
server_executable: bin/rails
server_command: server
server_args: ["-p", "${port}"]
app_directory: /rails
port_env_var: PORT
startup_delay: 5
# Global environment variables for all applications
global_env:
RAILS_ENV: production
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
# Environment template with variable substitution
env:
RAILS_APP_DB: "${database}"
RAILS_APP_OWNER: "${owner}"
PIDFILE: "pids/${database}.pid"
# Individual application tenants
tenants:
- name: myapp
path: /
working_dir: /var/www/myapp
var:
database: "myapp_production"
owner: "My Company"
Framework Configuration¶
Navigator supports multiple web frameworks through the framework
section. This makes Navigator framework-independent while providing sensible Rails defaults:
applications:
framework:
runtime_executable: ruby # Runtime interpreter (ruby, node, python)
server_executable: bin/rails # Server command (bin/rails, server.js, manage.py)
server_command: server # Subcommand (server, runserver)
server_args: ["-p", "${port}"] # Arguments (port will be substituted)
app_directory: /rails # Working directory for apps
port_env_var: PORT # Environment variable for port
startup_delay: 5 # Seconds to wait before marking ready
Framework Examples¶
Configuration Fields¶
Field | Required | Description | Example |
---|---|---|---|
runtime_executable |
Yes | Runtime interpreter command | ruby , python , node |
server_executable |
Yes | Server script/command | bin/rails , manage.py , server.js |
server_command |
No | Subcommand for server | server , runserver |
server_args |
No | Additional arguments | ["-p", "${port}"] |
app_directory |
No | Working directory | /rails , /app (defaults to /app ) |
port_env_var |
No | Port environment variable | PORT (default) |
startup_delay |
No | Startup delay in seconds | 5 (default) |
Template Variables¶
${port}
- Dynamically allocated port number- Can be used in
server_args
for port substitution
Global Environment Variables¶
The global_env
section sets environment variables for all web applications:
applications:
global_env:
RAILS_ENV: production
DATABASE_URL: "${DATABASE_URL}"
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
REDIS_URL: "${REDIS_URL:-redis://localhost:6379}"
RAILS_SERVE_STATIC_FILES: "false" # Navigator handles static files
Common Global Variables¶
Variable | Purpose | Example |
---|---|---|
RAILS_ENV |
Rails environment | production , staging , development |
SECRET_KEY_BASE |
Rails secret key | From environment variable |
DATABASE_URL |
Database connection | PostgreSQL, MySQL, SQLite URLs |
REDIS_URL |
Redis connection | For caching and sessions |
RAILS_SERVE_STATIC_FILES |
Static file handling | false (let Navigator handle) |
Environment Templates¶
Use the env
section for variable substitution across tenants:
applications:
env:
# Database configuration per tenant
RAILS_APP_DB: "${database}"
DATABASE_URL: "postgresql://user:pass@localhost/${database}"
# Tenant-specific settings
RAILS_APP_OWNER: "${owner}"
RAILS_STORAGE: "${storage_path}"
RAILS_APP_LOGO: "${logo_file}"
# Process management
PIDFILE: "pids/${database}.pid"
Each tenant can define var
values that get substituted into the template.
Tenant Configuration¶
Basic Tenant¶
tenants:
- name: myapp # Unique identifier
path: / # URL path prefix
working_dir: /var/www/myapp # Rails application directory
Multi-Tenant Setup¶
tenants:
- name: client-a
path: /clients/a/
working_dir: /var/www/app
var:
database: "client_a_db"
owner: "Client A Inc"
storage_path: "/storage/client-a"
- name: client-b
path: /clients/b/
working_dir: /var/www/app
var:
database: "client_b_db"
owner: "Client B Ltd"
storage_path: "/storage/client-b"
Tenant-Specific Environment¶
Override environment variables per tenant:
tenants:
- name: main-app
path: /
working_dir: /var/www/app
env:
RAILS_ENV: production
SPECIAL_FEATURE: "enabled"
- name: staging-app
path: /staging/
working_dir: /var/www/app
env:
RAILS_ENV: staging
DEBUG_MODE: "true"
Advanced Configuration¶
Special Tenants¶
Mark tenants as special to skip variable substitution:
tenants:
- name: main-app
path: /
working_dir: /var/www/app
# Uses env template with variable substitution
var:
database: "main_db"
- name: cable
path: /cable
working_dir: /var/www/app
special: true # Skip variable substitution
env:
RAILS_ENV: production
CABLE_ADAPTER: redis
Pattern Matching¶
Use patterns for flexible routing:
tenants:
- name: api-v1
path: /api/v1/
working_dir: /var/www/api
- name: websocket
path: /ws/
match_pattern: "*/ws/*" # Matches any path with /ws/
working_dir: /var/www/websocket
Standalone Servers¶
Proxy to external services instead of Rails:
tenants:
- name: action-cable
path: /cable/
standalone_server: "localhost:28080" # Proxy to external server
- name: api-service
path: /api/
standalone_server: "api.internal.com:8080"
Process Limits¶
Control concurrent requests per tenant:
tenants:
- name: high-traffic
path: /
working_dir: /var/www/app
max_concurrent_requests: 10 # Limit concurrent requests
- name: websocket
path: /ws/
working_dir: /var/www/app
force_max_concurrent_requests: 0 # Unlimited (for WebSockets)
Configuration Examples¶
Single Application¶
applications:
global_env:
RAILS_ENV: production
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
DATABASE_URL: "${DATABASE_URL}"
tenants:
- name: app
path: /
working_dir: /var/www/app
Multi-Tenant SaaS¶
applications:
global_env:
RAILS_ENV: production
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
env:
DATABASE_URL: "postgresql://user:pass@localhost/${tenant_db}"
RAILS_APP_TENANT: "${tenant_name}"
STORAGE_PATH: "/storage/${tenant_id}"
REDIS_NAMESPACE: "${tenant_id}"
tenants:
- name: acme-corp
path: /acme/
working_dir: /var/www/saas
var:
tenant_db: "acme_production"
tenant_name: "Acme Corporation"
tenant_id: "acme"
- name: widget-inc
path: /widget/
working_dir: /var/www/saas
var:
tenant_db: "widget_production"
tenant_name: "Widget Inc"
tenant_id: "widget"
API + Admin Split¶
applications:
global_env:
RAILS_ENV: production
DATABASE_URL: "${DATABASE_URL}"
tenants:
- name: api
path: /api/
working_dir: /var/www/api
env:
API_MODE: "true"
CORS_ORIGINS: "*.example.com"
- name: admin
path: /admin/
working_dir: /var/www/admin
env:
ADMIN_MODE: "true"
SESSION_TIMEOUT: "3600"
- name: main
path: /
working_dir: /var/www/frontend
Development Setup¶
applications:
global_env:
RAILS_ENV: development
tenants:
- name: dev
path: /
working_dir: . # Current directory
env:
RAILS_LOG_LEVEL: debug
EAGER_LOADING: "false"
Variable Substitution¶
Syntax¶
${variable}
- Replace with variable value${variable:-default}
- Use default if variable not set- Variables defined in tenant's
var
section
Example¶
env:
DATABASE_URL: "postgresql://user:pass@${db_host:-localhost}/${database}"
STORAGE_PATH: "/storage/${environment}/${tenant_id}"
LOG_FILE: "/var/log/app-${tenant_id}.log"
tenants:
- name: production-client
var:
database: "client_prod"
db_host: "prod-db.example.com"
environment: "production"
tenant_id: "client1"
Results in:
DATABASE_URL=postgresql://user:pass@prod-db.example.com/client_prod
STORAGE_PATH=/storage/production/client1
LOG_FILE=/var/log/app-client1.log
Best Practices¶
1. Use Global Environment for Common Settings¶
global_env:
RAILS_ENV: production
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
RAILS_LOG_TO_STDOUT: "true"
RAILS_SERVE_STATIC_FILES: "false"
2. Template Repeated Patterns¶
# Instead of repeating in each tenant
env:
DATABASE_URL: "postgresql://user:pass@localhost/${db_name}"
REDIS_NAMESPACE: "${tenant_prefix}"
STORAGE_PATH: "/storage/${tenant_prefix}"
3. Secure Sensitive Data¶
# Good - use environment variables
global_env:
SECRET_KEY_BASE: "${SECRET_KEY_BASE}"
DATABASE_PASSWORD: "${DB_PASSWORD}"
# Bad - hardcoded secrets
global_env:
SECRET_KEY_BASE: "hardcoded-secret" # Never do this!
4. Organize by Environment¶
# Production config
global_env:
RAILS_ENV: production
RAILS_LOG_LEVEL: info
# Development config
global_env:
RAILS_ENV: development
RAILS_LOG_LEVEL: debug
Troubleshooting¶
Rails App Won't Start¶
-
Check working directory:
-
Verify environment variables:
-
Test Rails manually:
Environment Variables Not Set¶
-
Check substitution:
-
Test manually:
Path Routing Issues¶
-
Check path conflicts:
-
Test routing: