Skip to content

Launch a new client site ​

From an empty folder to a site the client reviews on the server, and from there to live. The recipe follows the order the work happens in; the pages it links to hold the details and the options. Written against 2.16.0.

  • You need SSH access to the hosting account, a vhost per environment pointing at <target>/current/public, a DNS record and a MySQL database per environment, and the client's accounts for the integrations the site uses.
  • You get a deployed site with its posture (mail, indexing, password, banner) set by its environment type, cron jobs for the scheduler and the queue, and a documented switch to live.
  • Pages Installation, Environments, Deployment, Modules, Integrations

1. Create the project ​

sh
composer create-project racerfish/evolve-starter --ask --repository '{"type": "vcs", "url": "https://github.com/racerfish/evolve-starter"}' --remove-vcs

Composer asks for the folder name and installs the dependencies. The starter's install wizard writes the .env. Name the folder like the client; with Herd it becomes the local domain (client.test). Then:

sh
cd client
php artisan migrate
php artisan evolve:seed

Check: http://client.test/evolve shows the login screen. The first user comes from the panel's registration or an invitation, see Roles.

2. Switch the modules ​

Decide which modules the site uses, in config/evolve.php under modules or with EVOLVE_MODULE_<KEY> in the .env. Everything is on by default except the AI chatbot and regions; switch off what the site will not use so editors do not see it. Run php artisan migrate again after the first change.

Check: the panel sidebar lists exactly the modules you kept, one entry each. The table on Modules says what each adds.

3. Publish blueprints and the theme ​

Without published blueprint classes no block renders:

sh
php artisan vendor:publish --tag=evolve.blueprints
php artisan vendor:publish --tag=blog.blueprints --tag=company.blueprints --tag=event.blueprints --tag=scout24.blueprints
php artisan vendor:publish --tag=locator.components --tag=shopify.components --tag=scout24.components

Publish only the tags of modules the site uses. Then the theme:

sh
php artisan theme:publish
yarn theme:install
yarn theme:dev

Check: add a text block to the seeded home page in the panel and open http://client.test/. The block renders. The theme is now the project's to shape, see Frontend.

4. Keys and settings ​

The .env carries what the site cannot run without: APP_URL (the page cache and the sitemap depend on it), the database, the mail transport, and the secrets of the integrations you switched on (reCAPTCHA, Google Maps and Geocoding for the locator, Vimeo, OpenAI). The starter's .env.example 2.19 is grouped and commented; it carries no site settings. Environment Variables is the reference, each row links to the page that explains the key.

The site's own values go into the panel, not the .env: log in at /evolve, open Settings and walk the tabs General (name, branding), Company, Mail (sender name and addresses), Tracking (ids, consent) and SEO (verifications). These are stored in the database and travel with the database copy in step 6; the secrets in the .env do not, every environment gets its own copy there.

Check: /evolve/health on the local site is green apart from checks that need the server (scheduler, queue).

5. Declare the environments ​

In config/evolve.php under deployment, name the environments and the server:

php
'deployment' => [
    'default' => env('DEPLOYMENT_DEFAULT', 'live'),
    'environments' => [
        // the future live site, declared as staging while the client reviews it
        'staging' => ['type' => 'staging', 'target' => 'www', 'url' => 'https://client.ch'],
    ],
    'server' => [
        'user' => env('DEPLOYMENT_USER', 'web161'),
        'host' => env('DEPLOYMENT_HOST', 'web.onlime.ch'),
        'path' => env('DEPLOYMENT_PATH', 'webhome/public_html'),
        'php-bin' => env('DEPLOYMENT_PHP_BIN', 'php84'),
    ],
],

The type drives the posture: a staging site redirects mail, carries noindex, shows the banner and gets a password as soon as one is set; a live site does none of that and asks you to type its name before a deploy. The full matrix is on Environments.

Where the client reviews the site

The tooling never pushes a database into a live environment, not with evolve:db:copy, not with the Envoy tasks, not with evolve:env:setup --db=copy:.... Content built on a separate review site therefore cannot be moved into live later. So the declaration above names only one environment: the target that becomes the live site (www), declared as staging while the client reviews it, which gives it the mail redirect, noindex and the password. Step 8 turns that declaration into live. The permanent staging environment for the work after launch is set up at the end, seeded from live.

Check: php artisan evolve:env:list prints the declared environments.

6. Bootstrap the server and ship the first release ​

With the vhost, DNS and database in place on the hosting side:

sh
php artisan evolve:env:setup staging --db=fresh --deploy

The command asks you to type the name for a live environment, creates the remote directories, writes the server .env from the shipped template (it prompts for APP_URL, the database name, user and password; a prepared file passed with --from-file skips the prompts), runs the first deployment, and with --db=fresh seeds the database after the deploy. EVOLVE_ENV_TYPE is written from the declaration, so the posture is in place from the first request.

Then the two cron entries on the server, both pointing at current so they follow every deploy:

sh
* * * * * cd ~/webhome/public_html/www/current && php84 artisan schedule:run >> /dev/null 2>&1
* * * * * cd ~/webhome/public_html/www/current && php84 artisan queue:work --stop-when-empty --max-time=55 >> /dev/null 2>&1

The worker line is needed once QUEUE_CONNECTION is not sync; add it in the same step as that change, see Cron jobs.

Check:

sh
php artisan evolve:env:verify staging     # posture matches the declaration
php artisan evolve:remote:status staging  # current release, PHP, queue and scheduler

The site answers on its URL with the environment banner, /evolve/health shows the Scheduler check green within a minute, and the first user can log in.

7. Posture, content and integrations on the review site ​

In the panel under Settings, Developers tab (developer role):

  • Mail safety stays on; set EVOLVE_MAIL_REDIRECT to your own address so form notifications and invitations reach you instead of the client. Switch it to real recipients only for a dress rehearsal.
  • Protect with EVOLVE_PROTECT_USER and EVOLVE_PROTECT_PASSWORD before you send the client the URL the vhost answers on (the hosting's preview hostname, or the domain once its DNS points at the server). The password and the page cache exclude each other, so the cache stays off while the site is protected.
  • Tracking emit stays off. The IDs can sit in the .env already; a staging site does not fire them. The test run is its own recipe, Set up tracking and consent.

Invite the client's editors from Users; invitations are signed links. Editors build the content here. Media uploads land in shared/storage/app and survive every deploy.

Connect the integrations the site uses, each from its checklist on Integrations: reCAPTCHA keys registered for the live domain and, if the check should run there, the staging domain; the Sentry DSN; the Oh Dear health check secret; Vimeo, Brevo and OpenAI where the site uses them.

Check: a form submission on the review site produces a lead in the panel and a mail in your redirect inbox. /evolve/health is green except Oh Dear, which only reports once the site is live and monitored.

8. Go live ​

  1. Rename the declaration: the key becomes live, the type live, the target stays www. The name is what you type on the CLI, the target is the directory on the server, so nothing moves.
php
'environments' => [
    'live' => ['type' => 'live', 'target' => 'www', 'url' => 'https://client.ch'],
],
  1. On the server side, set the environment type to live in the Developers tab, which writes APP_ENV=production and EVOLVE_ENV_TYPE=live together. Turn mail safety off and remove the preview password in the same screen. Switch the page cache on under General if the site uses it.
  2. Deploy once more. A deploy to live asks you to type the environment name:
sh
php artisan deploy live
php artisan evolve:env:verify live

evolve:env:verify fails while APP_ENV or EVOLVE_ENV_TYPE contradict the declaration or debug is on, and warns about a missing Sentry DSN, an APP_URL that differs from the declared one, keys missing against .env.example and a stale published Livewire bundle. Fix what it names and run it again.

  1. Point the DNS at the server and set up the Oh Dear monitor for the live URL, see Oh Dear.

Check:

sh
curl -s https://client.ch/ | grep -c gtm.js                   # 1 once tracking is configured
curl -s https://client.ch/ | grep -E '<title>|rel="canonical"' # the live domain, no noindex
php artisan evolve:remote:status live

/evolve/health is green, the Oh Dear check included. sitemap.xml lists the pages.

9. A staging environment for the work after launch ​

Now that live has content, add the declaration for the permanent staging site and set it up from live:

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

With the vhost, DNS record and database for it in place:

sh
php artisan evolve:env:setup staging --from=live --db=copy:live --media-from=live --deploy

--from=live seeds the server .env from the live one (the type and posture keys come from the declaration), --db=copy:live copies the database on the server and runs the sanitize statements under deployment.database.sanitize, --media-from=live copies the uploads. Add the cron entries for the staging target as in step 6.

Check: php artisan evolve:env:verify --all passes for both, and the staging site shows the banner, carries noindex and redirects its mail.

Done when ​

  • evolve:env:verify --all passes.
  • /evolve/health is green on live, Oh Dear included.
  • The scheduler and, where the queue is not sync, the worker run from cron on every environment.
  • The client's editors log in with their own accounts and the first lead has arrived at the client's address.
  • Tracking fires on live, see the tracking recipe.