Appearance
Laravel Cloud
Laravel Cloud is Laravel's own platform: no server to set up or update, a deploy on every push, zero-downtime releases, the database, buckets, workers and the scheduler added from its dashboard. Two things about it shape a kitloom site there: the file system is reset on every deploy, and each replica of the app has its own. So the uploads live in a bucket, the caches are built in the build, and nothing the site writes to its own disk is meant to last. What the server needs and where else to host: Deployment.
With the deploy kit
bash
php artisan kitloom:deploy-kit laravel-cloud --domain=example.comCloud keeps its settings in its dashboard, not in files, so the kit writes the checklist below with this site's values and the variables to paste:
| File | What it is |
|---|---|
deploy/README.md | The checklist: the application and its PHP version, the resources (Laravel MySQL, the public media bucket, a private bucket when Import & Export or Backup use one, Valkey with Horizon), the build commands with your token (and Nova's), the deploy command, the scheduler and the worker, the first deploy, backups |
deploy/laravel-cloud.env | The variables next to what Cloud fills in: MEDIA_DISK=media, MEDIA_UPLOADS_URL to fill, IMPORT_EXPORT_DISK=private when the module is there, KITLOOM_MODULES_CACHES=deploy, the queue on Valkey with Horizon, DB_PREFIX for a WordPress database, and why each |
The S3 adapter the bucket needs is asked for (composer require league/flysystem-aws-s3-v3) only while it is missing.
Step by step
What the kit's checklist holds, in full. Laravel Cloud is Laravel's own platform: no server to set up or update, a deploy on every push, zero-downtime releases, the database, buckets, workers and the scheduler added from its dashboard. Two things about it shape a kitloom site there: the file system is reset on every deploy, and each replica of the app has its own. So the uploads live in a bucket, and nothing the site writes to its own disk is meant to last.
1. The application
Sign up at cloud.laravel.com, connect GitHub, GitLab or Bitbucket, and create an application from your site's repository — the project you created with composer create-project and committed. Pick the region closest to your visitors. In the environment's General settings, choose PHP 8.4 or newer; the extensions kitloom needs (intl, gd, imagick, pdo_mysql, redis, pcntl) are all there.
On your machine, add the S3 adapter the bucket needs, and commit it:
bash
composer require league/flysystem-aws-s3-v32. The resources
On the environment's canvas:
- Add database → Laravel MySQL. Cloud fills
DB_HOST,DB_DATABASEand the rest itself. Not Serverless Postgres: kitloom runs on WordPress's MySQL tables. SQLite does not work on Cloud, its file would be gone with the next deploy. A site moving from WordPress loads WordPress's database into it through the database's public endpoint, with any MySQL client (see Migrate from WordPress) and setsDB_PREFIXto its$table_prefix(wp_unless it was changed). - Add bucket → Laravel Object Storage, with public visibility and the disk name
media: the media library's uploads. Public files are what the site shows; a public bucket is read by everyone who has an address. - A second, private bucket, disk name
private, for what must not be public: a WXR file waiting for its import (the queue worker reads it, and it may run on another instance) and backup archives. - Cache: not needed at first, the database keeps the cache and the sessions. Add Laravel Valkey when the site grows or runs several replicas.
- Email: Cloud's email resource (Resend), or any mailer of your own.
3. The environment
In General settings → Environment variables, next to what Cloud fills in itself:
ini
APP_THEME=Journal # the theme, or empty for a headless site
MEDIA_DISK=media
MEDIA_UPLOADS_URL=https://… # the public bucket's address, from its settings page
IMPORT_EXPORT_DISK=private
KITLOOM_MODULES_CACHES=deploy # see below
CACHE_STORE=database
SESSION_DRIVER=database
QUEUE_CONNECTION=database
# DB_PREFIX=wp_ # a WordPress database: its $table_prefix
# SENTRY_LARAVEL_DSN=… # with the Sentry module, optionalWhy these differ from a server:
KITLOOM_MODULES_CACHES=deploy. Switching a module on the Modules screen works as anywhere, but the caches aren't rebuilt in place on Cloud. They come fromphp artisan optimizein the build, which may not reach your database; then it builds them with every module on, and the site uses them only while every module is on. While one is switched off, the site runs without its config and route caches — a little slower, never wrong — and a redeploy builds them the same way again, so there is no need to redeploy after a switch. See Enabling & Disabling.SENTRY_LARAVEL_DSN, optional. The Sentry module keeps a copy of its settings on each instance's disk, so that errors reach Sentry even when the database is down. After a deploy each instance writes its copy again on its first request; the DSN as a variable also covers a database that is down right after a deploy.- The page cache (Settings → Cache) works as it is, but
SITE_CACHE_STATICdoes not: its files would sit on one replica and vanish with the next deploy.
4. Build and deploy commands
Build commands (environment settings → Deployments), which also save your kitloom token for this build:
bash
composer config http-basic.packages.kitloom.dev <your-name> <your-token>
composer install --no-dev --optimize-autoloader
npm ci --audit false
npm run build:themes
php artisan optimizeThe token stays in Cloud's settings, not in your repository. A Nova site adds the same line for nova.laravel.com with your Nova license. A Blade-only site can leave out the two npm lines. php artisan optimize belongs here, in the build, not in the deploy commands: the caches are then part of the release.
Deploy commands, run just before a release goes live:
bash
php artisan migrate --forceNo storage:link (the uploads are in the bucket), no queue:restart (Cloud restarts the workers itself), no optimize:clear.
5. The queue and the scheduler
Click the App cluster:
- Scheduler on: Cloud runs
schedule:runevery minute, and wakes a sleeping environment to do it. - Background processes → New background process → Queue worker, one process for a start. A site with the Horizon module and its queue in Valkey runs
php artisan horizonas a custom process instead. When imports, backups or search indexing get heavy, move the workers to a worker cluster of their own, so they don't take the CPU from visitors. - Inertia SSR with a Vue or React theme:
php artisan inertia:start-ssrrenders the pages from thebootstrap/ssrthe build wrote — Cloud's own Inertia SSR setting for the environment where it offers it, else a Custom background process with that command. Without it the pages are drawn in the browser.
6. The first deploy
Deploy. Then, with the dashboard's Commands, make the first administrator — or skip it when the database came from WordPress or from your machine with its users:
bash
php artisan kitloom:user --login=admin [email protected] --no-interactionWith --no-interaction the password is made up and shown once in the command's output. Add your domain under Domains; until then the site answers on its free laravel.cloud address. Site Health in the admin then shows whether the scheduler and the worker come by, and checks the settings above. Laravel Cloud is recognised by itself, so Files kept between deploys lists whatever the site still keeps on the instance's disk — uploads, IMPORT_EXPORT_DISK, SITE_CACHE_STATIC, the cache or sessions on file, SQLite. Uploads address warns when the bucket gives the uploads no public address, and Backup destinations when backups are in use and their only destination is "This server". Each is a warning to act on, not an error.
Backups on Cloud: Laravel MySQL keeps its own for the days its backup retention is set to (two or more for a live site), and the Backup module archives the database to the private bucket (its S3 destination, with the key, secret, endpoint and bucket from the bucket's settings page) or any other storage (its "This server" destination would be gone with the next deploy). The uploads in the bucket are not in the archive: the bucket keeps them.