API-driven framework for building realtime apps, using MVC conventions (based on Express and Socket.io)
—
Sails.js provides a unified configuration system that merges settings from multiple sources, enabling flexible environment-specific configuration with runtime access and validation. The configuration system supports .sailsrc files, environment variables, command-line arguments, and programmatic overrides.
Load configuration from .sailsrc files, environment variables, and command-line arguments:
sails.getRc(namespace?: String): DictionaryParameters:
namespace (String, optional) - Configuration namespace (default: 'sails')Returns: Dictionary - Merged configuration object from all sources
Configuration Sources (in precedence order):
minimist).sailsrc files (current directory and upward).sailsrc files (home directory)Example:
// Get default Sails configuration
const config = sails.getRc();
console.log('Port:', config.port);
console.log('Environment:', config.environment);
console.log('Log level:', config.log?.level);
// Get custom namespace configuration
const appConfig = sails.getRc('myapp');
console.log('Custom config:', appConfig);
// Programmatic configuration access
console.log('Database URL:', sails.getRc().datastores?.default?.url);sails.config // Dictionary - Complete merged configurationExample:
// Access configuration at runtime
console.log('Current port:', sails.config.port);
console.log('Environment:', sails.config.environment);
console.log('Database config:', sails.config.datastores);
// Check feature flags
if (sails.config.myapp?.featureFlags?.newUI) {
console.log('New UI enabled');
}
// Access hook configurations
console.log('Blueprint settings:', sails.config.blueprints);
console.log('Security settings:', sails.config.security);Environment variables with the SAILS_ prefix are automatically parsed using rttc.parseHuman:
# Basic configuration
export SAILS_PORT=3000
export SAILS_ENVIRONMENT=production
# Nested configuration (use double underscores for nesting)
export SAILS_LOG__LEVEL=verbose
export SAILS_MODELS__MIGRATE=drop
export SAILS_DATASTORES__DEFAULT__URL=mysql://user:pass@host:3306/db
# Array configuration
export SAILS_CORS__ALLOW_ORIGINS='["https://app.com", "https://admin.com"]'
# Boolean configuration
export SAILS_BLUEPRINTS__REST=true
export SAILS_SECURITY__CSRF=falseEnvironment Variable Parsing Examples:
// SAILS_PORT=3000 → config.port = 3000 (number)
// SAILS_LOG__LEVEL=verbose → config.log.level = 'verbose' (string)
// SAILS_MODELS__MIGRATE=drop → config.models.migrate = 'drop'
// SAILS_CORS__ALLOW_ORIGINS='["https://app.com"]' → config.cors.allowOrigins = ['https://app.com']
// SAILS_BLUEPRINTS__REST=true → config.blueprints.rest = true (boolean)JSON configuration files loaded automatically:
Local .sailsrc (project directory):
{
"port": 1337,
"environment": "development",
"log": {
"level": "verbose"
},
"models": {
"migrate": "alter"
},
"datastores": {
"default": {
"adapter": "sails-mysql",
"host": "localhost",
"port": 3306,
"user": "root",
"database": "myapp_dev"
}
}
}Global .sailsrc (home directory):
{
"generators": {
"modules": {}
},
"commands": {
"generate": {
"templatesDirectory": "~/.sails-templates"
}
}
}Configuration via command-line arguments using minimist:
# Basic arguments
sails lift --port=4000 --environment=staging
# Nested arguments
sails lift --log.level=silly --models.migrate=safe
# Boolean flags
sails lift --prod --verbose
# Array arguments
sails lift --cors.allowOrigins=https://app.com,https://admin.comArgument Parsing:
// --port=4000 → config.port = 4000
// --log.level=silly → config.log.level = 'silly'
// --prod → config.environment = 'production'
// --verbose → config.log.level = 'verbose'Sails applications use configuration files in the config/ directory:
config/env/development.js:
module.exports = {
port: 1337,
models: {
migrate: 'alter'
},
datastores: {
default: {
adapter: 'sails-mysql',
host: 'localhost',
user: 'root',
password: '',
database: 'myapp_dev'
}
},
log: {
level: 'verbose'
}
};config/env/production.js:
module.exports = {
port: process.env.PORT || 80,
models: {
migrate: 'safe'
},
datastores: {
default: {
adapter: 'sails-mysql',
url: process.env.DATABASE_URL
}
},
log: {
level: 'error'
},
security: {
cors: {
allowOrigins: process.env.ALLOWED_ORIGINS?.split(',') || []
}
},
session: {
secret: process.env.SESSION_SECRET,
cookie: {
secure: true,
maxAge: 24 * 60 * 60 * 1000 // 24 hours
}
}
};config/datastores.js:
module.exports.datastores = {
default: {
adapter: 'sails-mysql',
host: 'localhost',
port: 3306,
user: 'myapp',
password: 'secret',
database: 'myapp'
},
redis: {
adapter: 'sails-redis',
host: 'localhost',
port: 6379,
db: 0
},
mongodb: {
adapter: 'sails-mongo',
url: 'mongodb://localhost:27017/myapp'
}
};config/routes.js:
module.exports.routes = {
// Static routes
'GET /': 'PageController.home',
'GET /about': { view: 'pages/about' },
// API routes
'POST /api/login': 'AuthController.login',
'DELETE /api/logout': 'AuthController.logout',
// RESTful routes
'GET /api/users': 'UserController.find',
'POST /api/users': 'UserController.create',
'GET /api/users/:id': 'UserController.findOne',
'PUT /api/users/:id': 'UserController.update',
'DELETE /api/users/:id': 'UserController.destroy',
// Catch-all route
'/*': { view: '404', skipAssets: true }
};config/models.js:
module.exports.models = {
// Default datastore
datastore: 'default',
// Migration strategy
migrate: 'alter', // 'alter', 'drop', or 'safe'
// Model settings
attributes: {
id: { type: 'string', columnName: 'id' },
createdAt: { type: 'number', autoCreatedAt: true },
updatedAt: { type: 'number', autoUpdatedAt: true }
},
// Validation
schema: true
};config/http.js:
module.exports.http = {
port: process.env.PORT || 1337,
middleware: {
order: [
'cookieParser',
'session',
'bodyParser',
'compress',
'methodOverride',
'router',
'www',
'favicon'
],
// Custom middleware
requestLogger: (req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
},
// Built-in middleware configuration
bodyParser: {
urlencoded: { extended: true },
json: { limit: '10mb' }
}
},
// SSL configuration
ssl: {
key: require('fs').readFileSync('./ssl/private-key.pem'),
cert: require('fs').readFileSync('./ssl/certificate.pem')
},
// Trust proxy
trustProxy: true,
// Static file caching
cache: 365.25 * 24 * 60 * 60 * 1000 // 1 year
};config/security.js:
module.exports.security = {
cors: {
allRoutes: true,
allowOrigins: [
'http://localhost:3000',
'https://myapp.com',
'https://admin.myapp.com'
],
allowCredentials: false,
allowRequestMethods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
allowRequestHeaders: 'content-type,authorization'
},
csrf: {
grantTokenViaAjax: true,
origin: 'https://myapp.com',
routesDisabled: ['/api/webhook/*']
}
};config/blueprints.js:
module.exports.blueprints = {
// Action routes (e.g. GET /user/find)
actions: false,
// RESTful routes (e.g. GET /user, POST /user)
rest: true,
// Shortcut routes (e.g. GET /user/create?name=John)
shortcuts: true,
// Route prefix
prefix: '/api/v1',
// Pluralize model names in URLs
pluralize: true,
// Auto-subscribe to model changes
autoWatch: true,
// Default limit for find operations
defaultLimit: 30
};config/custom.js:
module.exports.custom = {
// API keys
stripeSecretKey: process.env.STRIPE_SECRET_KEY,
sendgridApiKey: process.env.SENDGRID_API_KEY,
// Feature flags
featureFlags: {
newUserInterface: process.env.NEW_UI === 'true',
betaFeatures: false,
maintenanceMode: false
},
// Business logic configuration
pagination: {
defaultLimit: 25,
maxLimit: 100
},
// File upload settings
uploads: {
maxBytes: 10 * 1024 * 1024, // 10MB
allowedTypes: ['image/jpeg', 'image/png', 'image/gif'],
uploadPath: './assets/uploads'
},
// Email settings
email: {
from: 'noreply@myapp.com',
templates: {
welcome: 'email-welcome',
passwordReset: 'email-password-reset'
}
}
};config/env/staging.js:
module.exports = {
// Inherit from production but override specific settings
log: {
level: 'verbose' // More verbose logging for staging
},
models: {
migrate: 'alter' // Allow schema changes in staging
},
custom: {
featureFlags: {
betaFeatures: true // Enable beta features in staging
}
}
};// Validate required configuration at startup
module.exports = {
// config/bootstrap.js
fn: async function() {
// Check required environment variables
const required = ['DATABASE_URL', 'SESSION_SECRET', 'STRIPE_SECRET_KEY'];
const missing = required.filter(key => !process.env[key]);
if (missing.length > 0) {
throw new Error(`Missing required environment variables: ${missing.join(', ')}`);
}
// Validate configuration values
if (sails.config.custom.pagination.maxLimit > 1000) {
throw new Error('Maximum pagination limit cannot exceed 1000');
}
}
};// Define configuration schema for validation
const configSchema = {
port: { type: 'number', min: 1, max: 65535 },
environment: { type: 'string', isIn: ['development', 'staging', 'production'] },
log: {
type: 'dictionary',
properties: {
level: { type: 'string', isIn: ['silly', 'verbose', 'info', 'warn', 'error', 'silent'] }
}
}
};
// Validate configuration
const rttc = require('rttc');
try {
rttc.validate(configSchema, sails.config);
console.log('Configuration is valid');
} catch (err) {
console.error('Configuration validation failed:', err);
}// Use local environment for development
module.exports = {
port: 1337,
environment: 'development',
// Detailed logging
log: { level: 'verbose' },
// Schema migration
models: { migrate: 'alter' },
// Local database
datastores: {
default: {
adapter: 'sails-disk' // File-based for development
}
},
// Development-friendly settings
blueprints: {
shortcuts: true,
rest: true
}
};// Secure production configuration
module.exports = {
port: process.env.PORT || 80,
environment: 'production',
// Minimal logging
log: { level: 'error' },
// Safe database migration
models: { migrate: 'safe' },
// Production database
datastores: {
default: {
adapter: 'sails-mysql',
url: process.env.DATABASE_URL,
ssl: true
}
},
// Security settings
security: {
cors: {
allowOrigins: process.env.ALLOWED_ORIGINS.split(',')
}
},
// Disable development features
blueprints: {
shortcuts: false
}
};The Sails.js configuration system provides comprehensive flexibility for managing application settings across different environments, with multiple configuration sources, runtime access, and validation capabilities.
Install with Tessl CLI
npx tessl i tessl/npm-sails