Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

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-disable

The 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/',
    ],
];
KeyMeaning
config_glob_pathsWhich files from config/autoload to read
config_cache_enabledWhether to save the merged configuration to a file
module_map_cache_enabledWhether to save the module class map
cache_dirThe 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
StepWhy
git pullGet the new code
composer install --no-devInstall packages without development tools
--optimize-autoloaderSpeed up class lookup
rm -f data/cache/*.phpClear 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.

Thanks for reading!

Donate to the site — we work hard for you.