Managed Processes¶
Navigator can start and manage additional processes alongside your Rails applications, such as Redis, Sidekiq, background workers, and other services.
Basic Configuration¶
managed_processes:
- name: redis
command: redis-server
args: ["--port", "6379"]
working_dir: /var/lib/redis
auto_restart: true
start_delay: 0
Process Configuration¶
Field | Type | Required | Description |
---|---|---|---|
name |
string | ✓ | Unique process identifier |
command |
string | ✓ | Command to execute |
args |
array | Command line arguments | |
working_dir |
string | Working directory for the process | |
env |
object | Environment variables | |
auto_restart |
boolean | Restart process if it crashes | |
start_delay |
integer | Seconds to wait before starting |
Common Process Examples¶
Redis Server¶
managed_processes:
- name: redis
command: redis-server
args:
- --port 6379
- --appendonly yes
- --save 900 1
- --save 300 10
working_dir: /var/lib/redis
env:
REDIS_LOG_LEVEL: notice
auto_restart: true
start_delay: 0
Sidekiq Worker¶
managed_processes:
- name: sidekiq
command: bundle
args: [exec, sidekiq, -C, config/sidekiq.yml]
working_dir: /var/www/app
env:
RAILS_ENV: production
REDIS_URL: redis://localhost:6379/0
auto_restart: true
start_delay: 2 # Wait for Redis
Custom Background Worker¶
managed_processes:
- name: worker
command: python
args: [worker.py, --queue, high]
working_dir: /var/www/workers
env:
PYTHONPATH: /var/www/workers
LOG_LEVEL: info
auto_restart: true
start_delay: 1
Monitoring Service¶
managed_processes:
- name: prometheus
command: prometheus
args:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/var/lib/prometheus
- --web.console.libraries=/etc/prometheus/console_libraries
working_dir: /var/lib/prometheus
auto_restart: true
start_delay: 0
Process Lifecycle¶
Startup Order¶
Navigator starts processes in the order defined in configuration:
managed_processes:
# 1. Start Redis first
- name: redis
command: redis-server
start_delay: 0
# 2. Start Sidekiq after Redis
- name: sidekiq
command: bundle
args: [exec, sidekiq]
start_delay: 2 # Wait for Redis to be ready
# 3. Start monitoring last
- name: monitor
command: ./monitor.sh
start_delay: 5 # Wait for other services
Shutdown Order¶
Navigator stops processes in reverse order:
- Rails applications stop first
- Managed processes stop in reverse order (last started, first stopped)
- This preserves dependencies (Rails → Sidekiq → Redis)
Auto-Restart Behavior¶
managed_processes:
- name: critical-service
command: ./critical
auto_restart: true # Restart on any exit
- name: optional-service
command: ./optional
auto_restart: false # Don't restart (default)
Auto-restart triggers when: - Process exits with non-zero status - Process crashes or is killed - Process exits unexpectedly
Auto-restart does NOT trigger when: - Navigator is shutting down - Process is manually stopped - Process exits with status 0 (success)
Environment Variables¶
Global Environment¶
Environment variables are inherited from Navigator's environment:
Process-Specific Environment¶
managed_processes:
- name: worker1
command: ./worker
env:
WORKER_ID: "1"
QUEUE: "high"
REDIS_URL: redis://localhost:6379/1
- name: worker2
command: ./worker
env:
WORKER_ID: "2"
QUEUE: "low"
REDIS_URL: redis://localhost:6379/2
Environment Variable Substitution¶
Use Navigator's template system:
managed_processes:
- name: sidekiq
command: bundle
args: [exec, sidekiq]
env:
RAILS_ENV: "${RAILS_ENV:-production}"
DATABASE_URL: "${DATABASE_URL}"
REDIS_URL: "${REDIS_URL:-redis://localhost:6379}"
Multi-Process Patterns¶
Multiple Workers¶
managed_processes:
- name: redis
command: redis-server
auto_restart: true
# High priority queue worker
- name: sidekiq-high
command: bundle
args: [exec, sidekiq, -q, high, -c, "5"]
env:
REDIS_URL: redis://localhost:6379/0
auto_restart: true
start_delay: 2
# Low priority queue worker
- name: sidekiq-low
command: bundle
args: [exec, sidekiq, -q, low, -c, "2"]
env:
REDIS_URL: redis://localhost:6379/0
auto_restart: true
start_delay: 2
Multi-Tenant Workers¶
managed_processes:
- name: redis
command: redis-server
auto_restart: true
# Tenant-specific workers
- name: worker-tenant1
command: bundle
args: [exec, sidekiq, -q, tenant1]
env:
TENANT_ID: tenant1
DATABASE_URL: postgres://localhost/tenant1
auto_restart: true
start_delay: 2
- name: worker-tenant2
command: bundle
args: [exec, sidekiq, -q, tenant2]
env:
TENANT_ID: tenant2
DATABASE_URL: postgres://localhost/tenant2
auto_restart: true
start_delay: 2
Service Stack¶
managed_processes:
# Data layer
- name: redis
command: redis-server
auto_restart: true
- name: postgres
command: postgres
args: [-D, /var/lib/postgres/data]
auto_restart: true
# Application layer
- name: sidekiq
command: bundle
args: [exec, sidekiq]
auto_restart: true
start_delay: 3
# Monitoring layer
- name: metrics
command: ./metrics-collector
auto_restart: true
start_delay: 5
Working Directories¶
Absolute Paths (Recommended)¶
managed_processes:
- name: app-worker
command: bundle
args: [exec, sidekiq]
working_dir: /var/www/app # Absolute path
- name: data-processor
command: python
args: [process.py]
working_dir: /opt/processors # Absolute path
Relative Paths¶
# Relative to Navigator's working directory
managed_processes:
- name: local-worker
command: ./scripts/worker.sh
working_dir: ./workers # Relative to Navigator
Process-Specific Directories¶
managed_processes:
- name: redis
command: redis-server
working_dir: /var/lib/redis # Redis data directory
- name: log-processor
command: ./process-logs
working_dir: /var/log/app # Log directory
Security Considerations¶
Process Isolation¶
managed_processes:
# Run as specific user
- name: redis
command: sudo
args: [-u, redis, redis-server, /etc/redis/redis.conf]
# Limit resources
- name: worker
command: nice
args: [-n, "10", bundle, exec, sidekiq] # Lower priority
Secure Environment¶
managed_processes:
- name: secure-worker
command: bundle
args: [exec, worker]
env:
# Use environment variables for secrets
DATABASE_PASSWORD: "${DATABASE_PASSWORD}"
API_KEY: "${API_KEY}"
# Never hard-code secrets in config
File Permissions¶
# Ensure Navigator can execute commands
chmod +x /path/to/command
# Secure working directories
chmod 750 /var/lib/service
chown navigator:service /var/lib/service
Monitoring and Logging¶
Process Status¶
Navigator logs process events:
# Check process status in logs
grep "managed_processes" /var/log/navigator.log
# See process starts
grep "Starting process" /var/log/navigator.log
# See process crashes
grep "Process crashed" /var/log/navigator.log
Health Checks¶
managed_processes:
- name: redis
command: redis-server
auto_restart: true
# Health check process
- name: healthcheck
command: ./health-check.sh
args: [redis, sidekiq]
start_delay: 10
Log Management¶
managed_processes:
- name: sidekiq
command: bundle
args: [exec, sidekiq, --logfile, /var/log/sidekiq.log]
env:
RAILS_LOG_TO_STDOUT: "false" # Log to file instead
Troubleshooting¶
Process Won't Start¶
-
Check command exists:
-
Verify working directory:
-
Test manually:
Process Keeps Crashing¶
-
Check logs:
-
Disable auto-restart temporarily:
-
Add debugging:
Dependencies Not Ready¶
managed_processes:
- name: dependency
command: service
start_delay: 0
- name: dependent
command: client
start_delay: 5 # Increase delay
# Or add health check
- name: wait-for-redis
command: bash
args: [-c, "until redis-cli ping; do sleep 1; done"]
start_delay: 2
auto_restart: false
- name: sidekiq
command: bundle
args: [exec, sidekiq]
start_delay: 10 # Start after health check
Performance Tuning¶
Resource Limits¶
# Set limits before starting Navigator
ulimit -n 4096 # File descriptors
ulimit -u 2048 # Processes
ulimit -m 2097152 # Memory (KB)
./navigator config.yml
Process Concurrency¶
managed_processes:
# Scale workers based on CPU cores
- name: sidekiq
command: bundle
args: [exec, sidekiq, -c, "${SIDEKIQ_CONCURRENCY:-5}"]
# Multiple instances for CPU-bound work
- name: cpu-worker-1
command: ./cpu-intensive-task
- name: cpu-worker-2
command: ./cpu-intensive-task
Memory Management¶
managed_processes:
# Limit memory usage
- name: memory-limited
command: systemd-run
args:
- --scope
- --property=MemoryLimit=512M
- ./memory-hungry-process
Migration Patterns¶
From Systemd Services¶
# /etc/systemd/system/sidekiq.service
[Unit]
Description=Sidekiq
After=redis.service
[Service]
ExecStart=/usr/local/bin/bundle exec sidekiq
WorkingDirectory=/var/www/app
User=deploy
Becomes:
managed_processes:
- name: sidekiq
command: bundle
args: [exec, sidekiq]
working_dir: /var/www/app
auto_restart: true
From Docker Compose¶
# docker-compose.yml
services:
redis:
image: redis:latest
command: redis-server --appendonly yes
sidekiq:
build: .
command: bundle exec sidekiq
depends_on: [redis]
Becomes:
managed_processes:
- name: redis
command: redis-server
args: [--appendonly, yes]
- name: sidekiq
command: bundle
args: [exec, sidekiq]
start_delay: 2