Deploys and manages Laravel applications on Laravel Cloud using the `cloud` CLI. Use when the user wants to deploy an app, ship to Cloud, create or manage applications, environments, databases, caches, object storage, queues, domains, instances, background processes, secrets, compute, scheduled tasks, or Laravel Cloud infrastructure; or check billing, usage, or spend. Triggers on deployment, shipping, Cloud management, environment setup, database provisioning, billing or usage queries, the `cloud` CLI, and Laravel Cloud deployment troubleshooting.
73
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Use the Laravel Cloud documentation for detailed, current feature behavior. Use the Cloud CLI for Cloud operations rather than guessing dashboard or API workflows. Install it in the project and invoke it as ./vendor/bin/cloud by default; use a globally installed cloud command only as a fallback. Commands below are written as cloud for brevity; run them as ./vendor/bin/cloud unless falling back to the global installation.
composer install --no-dev && npm run build.php artisan migrate --force.php artisan queue:restart, php artisan horizon:terminate, php artisan optimize:clear, or php artisan storage:link to deploy commands. Cloud handles worker restarts and process management; deploy filesystem changes are not persistent.Storage::disk() with no arguments, such as Storage::disk()->put(...), so Laravel uses the environment's default disk. Do not pass a disk name for private/default storage. Attach a private Cloud bucket as the environment's default disk.Storage::disk('public')->put(...). Attach a second Cloud bucket configured as public and give it the public disk name.public.visibility: 'public' configuration for Cloud Object Storage. R2 does not support per-object ACL headers and rejects those requests; select the bucket visibility when creating the bucket.Storage::temporaryUrl(...). Public buckets expose all objects through their Cloud-provided public URL.composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies.aws/aws-sdk-php; check the current Cloud documentation before changing dependencies.php artisan schedule:run every minute. When an environment has multiple replicas, use Laravel's onOneServer for tasks that must run once.laravel.cloud domain after its first successful deployment. Cloud automatically verifies custom domains and provisions SSL after the required DNS records are configured.composer require --dev laravel/cloud-cli
./vendor/bin/cloud auth -nIf a project-local installation is not available, install the CLI globally with composer global require laravel/cloud-cli and invoke it as cloud.
cloud auth opens a browser. If a browser is unavailable, set LARAVEL_CLOUD_TOKEN in the environment. It overrides any saved token and writes nothing to disk. To save a token instead, run cloud auth:token --add --token=<token> -n or pipe it with echo "$TOKEN" | cloud auth:token --add -n.
Commands follow a CRUD pattern: resource:list, resource:get, resource:create, resource:update, resource:delete.
Available resources: application, environment, instance, database-cluster, database, cache, bucket, domain, websocket-cluster, background-process, secret, command, deployment.
Some resources have additional commands (e.g., domain:verify, database:open, instance:sizes, cache:types). Discover these via cloud -h.
Never hardcode command signatures. Always run cloud <command> -h to discover options at runtime.
-n to every command to prevent the CLI from hanging.-q or --silent; they suppress all output.Flag combos per operation:
:list, :get) → --json -n:create) → --json -n:update) → --json -n --force:delete) → -n --force (no --json)-n --force-n with all options passed explicitly (no --json)Determine the task and follow the matching path:
First deployment: inspect cloud ship -h, then run cloud ship -n with all required values.
Existing application:
cloud deploy {app_name} {environment} -n --open
cloud deploy:monitor -nEnvironment variables: cloud environment:variables -n --force
Secrets: echo "$VALUE" | cloud secret:create --name=NAME --json -n, then cloud environment-secret:attach
Provision infrastructure: cloud <resource>:create --json -n
Monorepo (application in a subdirectory): add --root-directory=<subdir> to cloud ship or cloud application:create.
Custom domain: cloud domain:create --json -n, then cloud domain:verify -n.
Repository defaults: cloud repo:config {application} -n sets repository-local application and organization defaults. Pass --organization=<id|name|slug> when the user has multiple organizations.
For multi-step operations, see reference/checklists.md.
:list --json -n or :get --json -n.cloud auth -n.Always run cloud deploy:monitor -n after every deploy. If it fails, inspect the deployment status and logs and show the user what went wrong before attempting a fix.
Delegate high-output operations to subagents using the Task tool to keep the main context window small. Only the summary returns; verbose output stays in the subagent's context.
Delegate these to a subagent:
cloud deploy:monitor -n — deployment logs can be very longcloud deployment:get --json -n — full deployment detailscloud <resource>:list --json -n — listing many resources produces large JSONcloud command:run — when output may be longcloud usage --detailed --json -n — the payload includes details for every database, cache, bucket, websocket, and applicationWebFetchKeep in the main context:
:create, :delete, :update — output is smallcloud deploy -n — you need the deployment ID immediatelyFollow these rules:
Use judgment for:
Secrets are encrypted values shared across the organization and attached to environments. The CLI encrypts values locally, so plaintext never reaches the API.
cloud secret:list --json -n
echo "$VALUE" | cloud secret:create --name=STRIPE_KEY --json -n
cloud environment-secret:attach {environment} {secretId} -n
cloud environment-secret:list {environment} --json -nPipe the value in. --value= works, but leaves the plaintext in shell history and the process list.
secret:update, secret:delete, and environment-secret:attach take secret IDs, not names — names are not unique. Read IDs from cloud secret:list --json -n.
There is no secret:get, and no way to detach a secret from a single environment. secret:delete removes it and detaches it everywhere.
Secrets need the sodium PHP extension. No other command does.
Redeploy affected environments after creating, updating, attaching, or deleting a secret.
Run PHP code directly in a Cloud environment:
cloud tinker {environment} --code='Your PHP code here' --timeout=60 -n--code — PHP code to execute (required in non-interactive mode)--timeout — maximum number of seconds to wait for output (default: 60)The code must explicitly output results using echo, dump, or similar; expressions alone produce no output.
Always pass --code and -n to avoid interactive prompts.
Run shell commands on a Cloud environment:
cloud command:run {environment} --cmd='your command here' -n--cmd — the command to run (required in non-interactive mode)--no-monitor — skip real-time output streaming--copy-output — copy output to clipboardReview past commands:
cloud command:list {environment} --json -n — list command historycloud command:get {commandId} --json -n — get details and output of a specific commandView billing and usage for the current organization:
cloud usage --json -n--period=current|previous|1|2|3 — Billing period (default: current; 1, 2, and 3 are one, two, and three periods back, respectively). Other values return an error.--environment=<id> — filter usage to a single environment--detailed — include per-application, per-resource, and per-add-on breakdowns--json — machine-readable output (always pair with -n)Common queries:
cloud usage --json -n | jq '.currentSpendCents'cloud usage --period=previous --json -ncloud usage --environment=<id> --detailed --json -nAll amounts are in cents. Keys are camelCase at every level (e.g., currentSpendCents, bandwidth.allowanceBytes, databases[].totalCents, applications[].totalCostCents).
LARAVEL_CLOUD_TOKEN — an API token, taking precedence over any saved one (empty counts as unset)~/.config/cloud/config.json — auth tokens and preferences.cloud/config.json — app and environment defaults (set by cloud repo:config {application} -n)Pass the application to repo:config. Without it, the command must prompt and fails under -n when the organization has more than one application. Deploy commands do not need these defaults; pass the application and environment to them directly.
Using multiple organizations requires multiple stored API tokens. Commands read organization_id from .cloud/config.json to select one and fail if it is not set. Set it with cloud repo:config {application} --organization=<id|name|slug> -n.
LARAVEL_CLOUD_TOKEN holds one token, so it picks the organization on its own. Naming a different one with --organization fails rather than falling back to the token's organization.
Laravel Cloud documentation: https://cloud.laravel.com/docs/llms.txt
When the user asks how something works or needs an explanation of a Laravel Cloud feature, fetch the docs from the URL above using WebFetch and use it to provide accurate answers.
cloud <command> -h for any command's optionscloud -h to discover commandscloud deploy:monitor -n.ff9c331
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.