| ← Back to Table of Contents | ← Back to Deployment |
8.1 Environment Setup and Variables
This document provides comprehensive reference for environment variables used in KMP deployment and configuration.
Overview
Environment variables control deployment-specific configuration without modifying code. They are loaded from .env files and support multiple deployment environments (development, staging, production) with a single codebase.
Important: Never commit .env files to version control. Each environment maintains its own .env file with sensitive credentials.
Environment Variable Categories
Environment variables in KMP are organized by function:
- Application: Debug mode, titles, encoding
- Database: Connection strings and credentials
- Security: Cryptographic salts and tokens
- Email: Transport configuration and sender settings
- Caching: Cache backend configuration
- Logging: Log destination and service URLs
- Timezone: Default timezone for date/time operations
- Document Storage: Cloud storage credentials (if using Azure or S3)
Core Variables Reference
Application Configuration
| Variable | Type | Purpose | Example |
|---|---|---|---|
DEBUG |
boolean | Enable debug mode and error display | false |
APP_ENCODING |
string | Character encoding | UTF-8 |
APP_DEFAULT_LOCALE |
string | Locale for internationalization | en_US |
APP_DEFAULT_TIMEZONE |
string | Default timezone | UTC |
BASE_SUB |
string|false | Subdirectory if app not in document root | false or /kmp |
SCRIPT_NAME |
string|null | Script name for non-mod_rewrite servers | /app.php or null |
Database Configuration
| Variable | Type | Purpose | Format |
|---|---|---|---|
DATABASE_URL |
string | Primary database connection | mysql://user:pass@host:port/db?encoding=utf8mb4 |
DATABASE_TEST_URL |
string | Test database connection | mysql://user:pass@host:port/test_db |
DB_HOST |
string | Database hostname | localhost |
DB_NAME |
string | Database name | kmp_production |
DB_USERNAME |
string | Database username | kmp_user |
DB_PASSWORD |
string | Database password | (sensitive) |
DB_PORT |
integer | Database port | 3306 |
DB_ENCODING |
string | Character encoding | utf8mb4 |
DB_TIMEZONE |
string | Database timezone | UTC |
Security Configuration
| Variable | Type | Purpose | Notes |
|---|---|---|---|
SECURITY_SALT |
string | Cryptographic salt | 32+ random characters, keep secret |
Generating a Security Salt:
php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"
Output is a 64-character random string suitable for use as SECURITY_SALT.
Email Configuration
| Variable | Type | Purpose | Example |
|---|---|---|---|
EMAIL_TRANSPORT_DEFAULT_URL |
string | Complete email transport config | smtp://user:pass@smtp.gmail.com:587?tls=true |
EMAIL_FROM_ADDRESS |
string | Default sender email | noreply@kingdom.example.com |
EMAIL_FROM_NAME |
string | Default sender display name | Kingdom Management Portal |
SMTP_HOST |
string | SMTP server hostname | smtp.gmail.com |
SMTP_PORT |
integer | SMTP server port | 587 (TLS) or 465 (SSL) |
SMTP_USERNAME |
string | SMTP authentication username | (service account) |
SMTP_PASSWORD |
string | SMTP authentication password | (sensitive) |
Email Transport Configuration Examples:
# Gmail with App Password
EMAIL_TRANSPORT_DEFAULT_URL=smtp://user@gmail.com:app_password@smtp.gmail.com:587?tls=true
# Generic SMTP
EMAIL_TRANSPORT_DEFAULT_URL=smtp://username:password@mail.example.com:587?tls=true
# SMTP without authentication
EMAIL_TRANSPORT_DEFAULT_URL=smtp://mail.example.com:25
Cache Configuration
| Variable | Type | Purpose | Example |
|---|---|---|---|
CACHE_CAKECORE_URL |
string | CakePHP core cache service | apcu:// or redis://localhost:6379 |
CACHE_CAKEMODEL_URL |
string | Model metadata cache service | apcu:// or redis://localhost:6379 |
Logging Configuration
| Variable | Type | Purpose | Format |
|---|---|---|---|
LOG_DEBUG_URL |
string | External service for debug logs | syslog://localhost:514 |
LOG_ERROR_URL |
string | External service for error logs | syslog://localhost:514 |
LOG_QUERIES_URL |
string | External service for query logs | syslog://localhost:514 |
LOG_PERFORMANCE_URL |
string | External service for request performance logs | syslog://localhost:514 |
Performance Monitoring Configuration
| Variable | Type | Purpose | Example |
|---|---|---|---|
PERF_REQUEST_LOG_ENABLED |
boolean | Enable request timing middleware logging | true / false |
PERF_SLOW_REQUEST_MS |
integer | Threshold for slow request warning logs | 750 |
PERF_LOG_ALL_REQUESTS |
boolean | Log all requests (not only slow ones) | false |
Document Storage Configuration
| Variable | Type | Purpose | Example |
|---|---|---|---|
AZURE_STORAGE_CONNECTION_STRING |
string | Azure Blob Storage credentials | (when using Azure) |
AWS_S3_BUCKET |
string | S3 bucket name | kmp-documents-prod |
AWS_DEFAULT_REGION |
string | S3 region | us-east-1 |
AWS_ACCESS_KEY_ID |
string | S3 access key (optional with IAM role) | AKIA... |
AWS_SECRET_ACCESS_KEY |
string | S3 secret key (optional with IAM role) | (sensitive) |
AWS_SESSION_TOKEN |
string | Temporary credentials token (optional) | (sensitive) |
AWS_S3_PREFIX |
string | Optional key prefix for document paths | kmp/documents/ |
AWS_S3_ENDPOINT |
string | Custom S3 endpoint (optional, MinIO etc.) | https://minio.example.com |
AWS_S3_USE_PATH_STYLE_ENDPOINT |
boolean | Force path-style S3 URLs | false |
The storage adapter (local, azure, or s3) is configured in config/app_local.php under Documents.storage.adapter, not via environment variable.
Environment Variable Files
.env File Format
Environment variables are loaded from .env files in the config/ directory:
# .env - Development environment (NOT version controlled)
# Debug mode
DEBUG=true
# Application settings
APP_DEFAULT_TIMEZONE=UTC
APP_ENCODING=UTF-8
# Database
DATABASE_URL=mysql://root:root@localhost/kmp_dev?encoding=utf8mb4
# Security
SECURITY_SALT=ARandomlyGeneratedSalt1234567890123456789012345678
# Email (development - uses Debug transport)
EMAIL_FROM_ADDRESS=dev@localhost
EMAIL_FROM_NAME=KMP Development
# Logging (development)
LOG_DEBUG_URL=
LOG_ERROR_URL=
LOG_PERFORMANCE_URL=
# Performance monitoring (off by default in dev)
PERF_REQUEST_LOG_ENABLED=false
PERF_SLOW_REQUEST_MS=750
PERF_LOG_ALL_REQUESTS=false
Configuration Hierarchy
KMP loads configuration in this order (see config/bootstrap.php):
.envfile - Loaded viajosegonzalez/dotenv, sets environment variablesconfig/app.php- Baseline configuration (usesenv()calls to read from step 1)config/app_local.php- Environment-specific overrides (if present)config/app_queue.php- Queue plugin configuration (if present)
Later values override earlier ones. Environment variables set in .env are consumed by env() calls in app.php.
Environment-Specific Examples
Development Environment
# .env
DEBUG=true
DATABASE_URL=mysql://root:root@localhost/kmp_dev?encoding=utf8mb4&timezone=UTC
SECURITY_SALT=dev_salt_not_secure_change_in_production
APP_DEFAULT_TIMEZONE=UTC
# Email - use Debug transport (files capture emails without sending)
EMAIL_FROM_ADDRESS=dev@localhost
EMAIL_FROM_NAME=KMP Development
# Logging
LOG_DEBUG_URL=
LOG_ERROR_URL=
LOG_PERFORMANCE_URL=
Staging Environment
# .env (Staging)
DEBUG=false
DATABASE_URL=mysql://staging_user:secure_password@staging-db.internal/kmp_staging?encoding=utf8mb4
SECURITY_SALT=staging_salt_must_be_cryptographically_random_64chars
APP_DEFAULT_TIMEZONE=America/Chicago
# Email - use staging SMTP server
EMAIL_TRANSPORT_DEFAULT_URL=smtp://staging@example.com:password@mail.staging.example.com:587?tls=true
EMAIL_FROM_ADDRESS=noreply-staging@kingdom.example.com
EMAIL_FROM_NAME=KMP Staging
# Logging to remote service
LOG_ERROR_URL=syslog://log-aggregator.internal:514
LOG_PERFORMANCE_URL=syslog://log-aggregator.internal:514
Production Environment
# .env (Production)
DEBUG=false
DATABASE_URL=mysql://prod_user:very_secure_password@prod-db.internal/kmp_production?encoding=utf8mb4&timezone=UTC
SECURITY_SALT=very_long_cryptographically_random_production_salt_here
APP_DEFAULT_TIMEZONE=America/Chicago
# Email - use production SMTP service
EMAIL_TRANSPORT_DEFAULT_URL=smtp://noreply@kingdom.com:secure_password@smtp.office365.com:587?tls=true
EMAIL_FROM_ADDRESS=noreply@kingdom.org
EMAIL_FROM_NAME=Kingdom Management Portal
# Logging to cloud service
LOG_ERROR_URL=syslog://logs.cloud-provider.com:514?protocol=tls
LOG_DEBUG_URL=syslog://logs.cloud-provider.com:514?protocol=tls
LOG_PERFORMANCE_URL=syslog://logs.cloud-provider.com:514?protocol=tls
# Caching
CACHE_CAKECORE_URL=redis://prod-redis-1.internal:6379
CACHE_CAKEMODEL_URL=redis://prod-redis-1.internal:6379
Security Best Practices
Securing Environment Variables
- Never commit
.envfiles - Add*.envto.gitignore - Restrict file permissions -
.envshould only be readable by app process:chmod 600 .env - Use strong values - Generate security salts and API keys with cryptographic randomness
- Rotate regularly - Change
SECURITY_SALTand password values periodically - Use managed secrets - Platforms like AWS Secrets Manager, Azure Key Vault, or HashiCorp Vault
- Audit access - Monitor which systems/users access environment variables
- Different per environment - Each environment (dev, staging, prod) has unique credentials
Sensitive Variables
These variables contain sensitive data and require special protection:
SECURITY_SALT- Cryptographic key materialDATABASE_URL- Database credentialsDB_PASSWORD- Direct database passwordSMTP_PASSWORD- Email service credentialsEMAIL_TRANSPORT_DEFAULT_URL- May contain email credentialsAZURE_STORAGE_CONNECTION_STRING- Storage account credentialsAWS_SECRET_ACCESS_KEY- S3 secret credentialsAWS_SESSION_TOKEN- Temporary S3 credentials token
Development Safety
In development environments:
- Use default credentials (user:
root, password:root) - Enable
DEBUG=truefor full error reporting - Accept self-signed SSL certificates
- Store in project
.env(added to.gitignore)
Production Safety
In production environments:
- Disable debug: Set
DEBUG=false - Use strong credentials: Random 32+ character passwords
- Use environment-specific values: Never reuse development credentials
- Store securely: Use cloud provider secret management
- Restrict access: Only the application process can read the
.envfile - Use TLS: Require TLS for database and SMTP connections
- Monitor changes: Alert on environment variable modifications
Variable Types and Casting
The env() function loads variables as strings. Use filter_var() for proper type conversion:
// Boolean conversion
$debug = filter_var(env("DEBUG", false), FILTER_VALIDATE_BOOLEAN);
// Integer conversion
$port = (int)env("SMTP_PORT", 25);
// URL parsing
$dbUrl = env("DATABASE_URL");
CakePHP automatically handles casting for built-in configurations like:
DATABASE_URL(parsed to connection array)EMAIL_TRANSPORT_DEFAULT_URL(parsed to transport settings)
Environment Variable Loading Behavior
.env File Loading
- Look for
.envinconfig/directory - Load variables into $_ENV and available to
env() - Variables already in environment take precedence
- Not found in
.envdefaults togetenv()
Recommended .env Approach
Place in config/.env:
# config/.env
# Copy from .env.example and customize for your environment
DEBUG=false
DATABASE_URL=mysql://...
SECURITY_SALT=...
Add to .gitignore:
config/.env
config/.env.local
.env
.env.local
Troubleshooting
Environment Variable Not Loading
- Check file location: Should be in
config/directory - Verify file syntax: No spaces around
=in assignments - Check file permissions: File must be readable by web process
- Clear cache: Run
bin/cake cache clear_all - Restart web server: PHP-FPM or Apache needs restart for changes
Incorrect Values Being Used
- Check variable name: Ensure correct spelling and case
- Check .env precedence: Variables in shell environment take precedence
- Clear APCu cache:
bin/cake cache clear_all(APCu caches variable access) - Verify .gitignore: Ensure no committed
.envfiles override local.env
Database Connection Issues
- Verify DATABASE_URL format: Should be
mysql://user:pass@host:port/db - Test credentials manually:
mysql -u user -p -h host db_name - Check firewall: Ensure host/port is accessible from app server
- Verify encoding: Include
?encoding=utf8mb4in connection string