Production Checklist
Complete guide to deploying VelvetCMS in production.
Follow this checklist before going live. Each step improves performance, security, or reliability.
Environment Configuration #
Application Settings #
// user/config/app.php
return [
'env' => 'production',
'debug' => false,
];
// user/config/logging.php
return [
'level' => 'warning', // or 'error' for less noise
'daily' => true, // rotate logs daily
'max_files' => 14, // keep 2 weeks
];
- debug must be
false- prevents exposing stack traces - level - reduce verbosity for production
- daily - enables log rotation to prevent disk fill
Cache Configuration #
./velvet config:cache
This compiles all config files into a single cached file, reducing file reads on every request.
Clear when you change configuration:
./velvet config:clear
PHP Configuration #
OPcache Settings #
Add to your php.ini:
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.fast_shutdown=1
Key points:
validate_timestamps=0- don't check file changes (deploy clears opcache)memory_consumption- increase for larger apps
PHP-FPM Tuning #
For high traffic, tune your PHP-FPM pool:
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
Adjust based on your server's memory and expected load.
Web Server #
Document Root #
Point your web server to the public/ directory:
root /var/www/velvet/public;
Never expose the project root - it contains sensitive files.
Deny Sensitive Paths #
Block access to configuration, storage, and vendor directories:
Nginx:
location ~ ^/(vendor|storage|config|database|bootstrap)/ {
deny all;
return 404;
}
location ~ /\. {
deny all;
}
See Nginx Configuration and Apache Configuration for complete examples.
Caching #
Application Cache #
If Redis is available, use it:
// user/config/cache.php
return [
'default' => 'redis',
'drivers' => [
'redis' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => 6379,
],
],
];
Route Caching #
./velvet route:cache
Speeds up route matching. Clear after adding/changing routes.
View Caching #
Compiled views are cached automatically. Clear if templates don't update:
./velvet view:clear
Database #
Connection Settings #
For MySQL/PostgreSQL, ensure persistent connections are enabled for long-running processes:
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'database' => env('DB_DATABASE', 'velvet'),
'username' => env('DB_USERNAME', 'velvet'),
'password' => env('DB_PASSWORD'),
// ...
],
Run Migrations #
./velvet migrate
Scheduled Tasks #
Add to your system crontab:
* * * * * cd /var/www/velvet && php velvet schedule:run >> /dev/null 2>&1
This runs the scheduler every minute - individual tasks run at their configured frequencies.
WebCron Alternative #
If system cron isn't available, enable WebCron:
// user/config/app.php
'cron_enabled' => true,
Then set up an external service to hit /system/cron every minute. See WebCron for security considerations.
Security #
HTTPS #
Ensure HTTPS is configured and HTTP redirects to HTTPS.
Session Security #
// user/config/session.php
return [
'secure' => true, // Cookies only over HTTPS
'same_site' => 'Lax', // Or 'Strict'
'httponly' => true, // No JavaScript access
];
File Permissions #
# Code directories: readable, not writable
chmod -R 755 src/ config/ public/ vendor/
# Storage: writable by web server
chmod -R 775 storage/
chown -R www-data:www-data storage/
For additional security measures (HTTP headers, CSP, HSTS, database user separation), see Security Hardening.
Monitoring #
Log Rotation #
Configure logrotate for VelvetCMS logs:
/var/www/velvet/storage/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
}
Health Check Endpoint #
Create a simple health check route:
$router->get('/health', function () {
return Response::json([
'status' => 'ok',
'timestamp' => time(),
]);
});
Use with uptime monitoring services.
Quick Checklist #
-
debug = false -
env = production - Config cached (
config:cache) - Routes cached (
route:cache) - OPcache enabled
- Document root is
public/ - Sensitive paths blocked
- HTTPS configured
- Session cookies secured
- Cron job installed
- Log rotation configured
- Database migrations run