Deployment
Deployment is moving the application from your computer to a server where visitors can see it. Two things matter on a server that do not matter in development: the visitor must not see error details, and the configuration must not be rebuilt on every request.
Production mode
On the server development mode is switched off:
composer development-disableThe command removes the files config/development.config.php and config/autoload/development.local.php. After that the visitor sees a generic error page instead of the exception text, and the configuration cache is allowed.
The configuration cache
Without a cache Laminas reads the files of every module on each request and merges them into one array. The cache is enabled in config/application.config.php:
// config/application.config.php
return [
'modules' => require __DIR__ . '/modules.config.php',
'module_listener_options' => [
'config_glob_paths' => [
realpath(__DIR__) . '/autoload/{{,*.}global,{,*.}local}.php',
],
'config_cache_enabled' => true,
'config_cache_key' => 'application.config.cache',
'module_map_cache_enabled' => true,
'module_map_cache_key' => 'application.module.cache',
'cache_dir' => 'data/cache/',
],
];| Key | Meaning |
|---|---|
config_glob_paths | Which files from config/autoload to read |
config_cache_enabled | Whether to save the merged configuration to a file |
module_map_cache_enabled | Whether to save the module class map |
cache_dir | The folder for cache files |
After the first request, files with the ready configuration appear in data/cache. In development mode these keys are overridden and the cache is off.
Local configuration
The file config/autoload/local.php is not kept in the repository. On the server it is created by hand and holds the production database password and other secrets.
The web server
The site root is the public folder. Every request that does not match a real file is passed to public/index.php. An example for nginx:
server {
listen 80;
server_name example.com;
root /var/www/blog/public;
index index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}For Apache the skeleton already ships public/.htaccess with the same rules. The data and public/uploads folders must be writable by the web server.
The update routine
git pull
composer install --no-dev --optimize-autoloader
composer development-disable
rm -f data/cache/*.php| Step | Why |
|---|---|
git pull | Get the new code |
composer install --no-dev | Install packages without development tools |
--optimize-autoloader | Speed up class lookup |
rm -f data/cache/*.php | Clear the configuration cache so the changes are picked up |
Changes to the database structure are applied separately — with SQL queries kept in the project.
Common mistake
Cached configuration cannot contain closures: they cannot be written to a file. A factory given in the configuration as function ($container) { ... } works in development and breaks the site on a server with the cache enabled. In config files name factories only by class names.