Skip to the content.
← 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:

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):

  1. .env file - Loaded via josegonzalez/dotenv, sets environment variables
  2. config/app.php - Baseline configuration (uses env() calls to read from step 1)
  3. config/app_local.php - Environment-specific overrides (if present)
  4. 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

  1. Never commit .env files - Add *.env to .gitignore
  2. Restrict file permissions - .env should only be readable by app process:
    chmod 600 .env
    
  3. Use strong values - Generate security salts and API keys with cryptographic randomness
  4. Rotate regularly - Change SECURITY_SALT and password values periodically
  5. Use managed secrets - Platforms like AWS Secrets Manager, Azure Key Vault, or HashiCorp Vault
  6. Audit access - Monitor which systems/users access environment variables
  7. Different per environment - Each environment (dev, staging, prod) has unique credentials

Sensitive Variables

These variables contain sensitive data and require special protection:

Development Safety

In development environments:

Production Safety

In production environments:

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:

Environment Variable Loading Behavior

.env File Loading

  1. Look for .env in config/ directory
  2. Load variables into $_ENV and available to env()
  3. Variables already in environment take precedence
  4. Not found in .env defaults to getenv()

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

  1. Check file location: Should be in config/ directory
  2. Verify file syntax: No spaces around = in assignments
  3. Check file permissions: File must be readable by web process
  4. Clear cache: Run bin/cake cache clear_all
  5. Restart web server: PHP-FPM or Apache needs restart for changes

Incorrect Values Being Used

  1. Check variable name: Ensure correct spelling and case
  2. Check .env precedence: Variables in shell environment take precedence
  3. Clear APCu cache: bin/cake cache clear_all (APCu caches variable access)
  4. Verify .gitignore: Ensure no committed .env files override local .env

Database Connection Issues

  1. Verify DATABASE_URL format: Should be mysql://user:pass@host:port/db
  2. Test credentials manually: mysql -u user -p -h host db_name
  3. Check firewall: Ensure host/port is accessible from app server
  4. Verify encoding: Include ?encoding=utf8mb4 in connection string

See Also