Skip to content

Environments ​

Since v2.6, Evolve treats deployment environments as first class citizens. A project declares its environments in config/evolve.php, each with a name, a type that drives policy, and a target directory on the server.

php
'deployment' => [
    'default' => env('DEPLOYMENT_DEFAULT', 'live'),

    'environments' => [
        'live'    => ['type' => 'live',    'target' => 'www',     'url' => 'https://client.ch'],
        'staging' => ['type' => 'staging', 'target' => 'staging', 'url' => 'https://staging.client.ch'],
    ],
    ...
],

The name is what you type on the CLI (php artisan deploy staging). The target is the physical directory under the server path and may keep its historical name. Development is the fourth type; it is your local machine and never declared as a remote.

Projects that still use the legacy target and allowed-targets keys keep working unchanged. The default target behaves as live and the allowed targets behave as staging.

Types and policies ​

Three types: development, staging, live. The type determines what the tooling allows and how the running site behaves. The policy lives in the package and is deliberately not configurable per project; single .env variables override single defaults, see Environment Variables. testing is still accepted in declarations and .env files written before 2.8 and means staging.

developmentstaginglive
Meant forthe local machine, or an early alpha on a serverevery remote test siteproduction
APP_ENV on the serverlocalstagingproduction
Debug (APP_DEBUG default)ononoff, evolve:env:verify fails otherwise
Outgoing mailas configured (Mailpit, log)redirected to EVOLVE_MAIL_REDIRECT until a developer switches it to realreal recipients
Frontend bannershownshownnone
Preview passwordneveras soon as EVOLVE_PROTECT_PASSWORD is setnever
Search enginesindexablenoindexindexable
Page cacheAPP_PAGE_CACHE, writes on production and staging onlysamesame
Deploy confirmationyes/no, --force skipsyes/no, --force skipstype the environment name, --force is ignored
Branch checkany branchany branchwarns off master, typed confirm
Database pushes into itconfirm plus backup plus sanitizesamenever

A staging site starts safe: mail is caught, the site is noindexed, and it is password protected the moment a password is set. The frontend banner is a small pill at the bottom centre naming the environment; a visitor can shrink it to a dot in the corner, and the browser remembers that choice. What it does beyond that is the developer's call, per site, in the Developers tab: switch mail to real recipients for a dress rehearsal, hide the banner, turn debug off. Nothing has to be declared twice.

A deployed test site runs APP_ENV=staging, never testing: Laravel interprets an app environment called testing as running unit tests, which changes framework behavior. Development can be declared as a remote environment too (an early alpha on a server); it then runs APP_ENV=local with the banner and without any mail redirect.

The runtime side is driven by EVOLVE_ENV_TYPE in the server .env, which evolve:env:setup writes automatically. Note that the preview protection and the page cache are mutually exclusive: cached pages are served without PHP, so while a protect password is set the cache does not write.

Commands ​

bash
# List declared environments
php artisan evolve:env:list

# Bootstrap a new environment: remote directories, server .env, database, media
php artisan evolve:env:setup staging --from=live --db=copy:live --media-from=live --deploy

# Verify an environment against its declaration
php artisan evolve:env:verify staging
php artisan evolve:env:verify --all

# Compare .env key names across .env.example, local .env and remote environments
php artisan evolve:env:diff

# Copy a database between environments, entirely on the server (never into live)
php artisan evolve:db:copy live staging

# Open an SSH session in an environment
php artisan evolve:ssh staging

evolve:env:setup needs three things prepared on the hosting side first: a vhost pointing at <target>/current/public, a DNS record, and the MySQL database. Everything else, including the first deployment, is handled by the command.

evolve:db:copy always writes a compressed backup of the destination database next to the target's releases/ directory before importing, and then runs the SQL statements configured under deployment.database.sanitize, which is the place to anonymize personal data on non live copies.

The destination ends up with exactly the tables of the source. The command first dumps the source into a file, then drops every table and view in the destination, and only then imports. Tables the source lacks (leftovers of earlier deploys on the destination) are gone afterwards, so the next migrate does not trip over them. If the source dump fails, the destination stays untouched. Before 2.22.3 the copy kept such leftover tables.

Migrating an existing project ​

  1. Update the package. Nothing breaks; the legacy config keeps working.
  2. Declare the environments map in config/evolve.php, keeping the historical directory names as targets.
  3. Run php artisan evolve:env:verify --all. It reports exactly what each server .env is missing, typically EVOLVE_ENV_TYPE and the switch of test sites from APP_ENV=production to staging.
  4. Fix the server .env files. Switching a test site to staging activates the noindex header, the mail redirect and, once a password is set, the basic auth gate. That is the point.

The environment in the settings panel ​

The Developers tab of the settings panel shows the environment. What a user can do there depends on the role:

  • A developer sees the technical cards: the environment type (which writes APP_ENV and EVOLVE_ENV_TYPE together, so they cannot drift), debug, the frontend banner, mail safety with the redirect address, the preview user and password, and one switch per module.
  • An admin sees the environment read only. Technical settings are a developer concern, and the server side drops those keys from an admin's save whatever the form sent.

The panel edits the .env of the instance it runs on; each environment keeps its own. The deployment writes the posture keys from the declaration in config/evolve.php when it bootstraps an environment, and evolve:env:verify compares the server .env against that declaration. The environment consistency health check does the same at runtime: it fails when APP_ENV and EVOLVE_ENV_TYPE contradict each other and warns on a remote without a declared type.

When EVOLVE_ENV_TYPE is not set at all, the type is inferred from APP_ENV: production means live, staging means staging, anything else means development. That is the state of a project that has not run the environment setup yet.

How mail behaves per environment is described on the Mail page; roles on Roles.