Laravel: your first steps

Last verified

Picked Laravel? Your site runs PHP behind nginx, with Composer and a MariaDB database, and is ready for your own Laravel app from Git. We do not install a blank Laravel project: your first deploy puts your app on the site. Until then it shows a page saying Your site is ready.

Before you start

Your repository needs artisan and composer.json at its top level, and your public/index.php in public/, as every Laravel app has. An app kept in a subfolder of the repository cannot be deployed yet.

Deploy your app

  1. Open Sites → your site → Deploys. On a new site the Deploy from your repository panel is already open.
  2. Connect your Git host and pick the repository, or paste its URL (Deploy from Git).
  3. Check Repository layout. It should start with We found: Laravel app at the top level, web root public/. and list the build.
  4. Press ✓ Deploy this way. Progress shows at the top of the tab, and Recent deploys keeps the log.

What every deploy runs

  1. In a separate build container, when you have a package.json: npm ci and your build script (Vite or Mix). Your environment variables are not available there.
  2. On your site: composer install --no-dev --optimize-autoloader.
  3. php artisan migrate --force. When your site has a database, a copy of it is saved first. Untick Run database migrations after deploying under Build steps to skip this.
  4. php artisan view:cache and php artisan storage:link.

We do not run config:cache, so a change to an environment variable applies without a new deploy. Change the build commands, or add a test command that must pass, under Build steps.

Settings and secrets

Do not commit your .env. Add your own settings (mail, API keys) under Configure → Environment variables; your app reads them with env() as usual. APP_KEY and your database's DB_* values are set for you, and the form refuses those names. See Environment variables.

Until you set them yourself, your app also gets:

  • APP_ENV=production
  • APP_URL: https:// and the address your site is served on. It follows your domain once that is connected.
  • SESSION_DRIVER=file and CACHE_STORE=file
  • QUEUE_CONNECTION=sync, or database while the queue worker runs
  • REDIS_HOST=/run/valkey/valkey.sock and REDIS_PORT=0: your site's own Valkey cache (see below)

Without these, Laravel would look for its sessions, cache and jobs in database tables a new app does not have. To use your own value, add a variable with the same name under Environment variables. A .env file on the site that sets one of these names also wins over ours, from your next deploy on. The Environment variables band lists each of these until you add your own variable of that name.

Redis (Valkey)

Your site has its own Valkey server, a Redis-compatible in-memory store, reachable only from inside the site. Laravel's redis drivers use it with the REDIS_HOST and REDIS_PORT above and no password: set CACHE_STORE=redis (or SESSION_DRIVER=redis, or QUEUE_CONNECTION=redis) under Environment variables and nothing else. It is a cache: it keeps no data across a restart and drops the oldest keys when it is full, so queued jobs you cannot lose belong in the database queue. This works with Laravel's default Redis client (phpredis).

To use a Redis server of your own elsewhere instead, set REDIS_HOST, REDIS_PORT and, if it has one, REDIS_PASSWORD under Environment variables.

A database

Your site gets its own MariaDB database when it is first set up. Open the site's Databases tab: for about a minute it says the database is being set up, then it shows the database's details. Under How your app reads this are the DB_* variables we set for your app (DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD). Laravel's default config/database.php reads exactly these.

If the tab shows no database (a site set up before Laravel sites got one), pick the engine and press Create database (Add database when your plan lets a site have several). If setting it up failed, the tab says so: press Retry.

The scheduler

Laravel's scheduler needs a cron entry. Open Configure → Scheduled tasks (cron), enter * * * * * as the Schedule and php artisan schedule:run as the Command, and press Add job. Scheduled tasks run with the same environment variables as your site, so the scheduler reaches your database. See Scheduled tasks (cron jobs).

Queues

With no queue worker, the default QUEUE_CONNECTION=sync runs a job your app queues straight away, inside the request that queued it. That is fine for quick jobs such as sending one email.

For slower jobs, turn on the queue worker: Configure → Queue worker, set Worker to On, pick how many Workers, and press Save. Within a minute it runs php artisan queue:work all the time, in your site, as your app user and with your environment variables. It processes the database queue:

  • Your site needs its database, and your app the jobs table. New Laravel apps include its migration; php artisan make:queue-table adds it otherwise.
  • While the worker runs, QUEUE_CONNECTION defaults to database instead of sync. A QUEUE_CONNECTION you set yourself, under Environment variables or in a .env, still wins.
  • A job is tried 3 times, and a worker restarts itself every hour.
  • Every deploy, rollback, restore, PHP version switch and environment variable change restarts the workers, so they always run your live code and settings.
  • How many workers you can run depends on your plan: one on Starter, more on bigger plans. The band says how many your site can have. Workers share your site's memory, and each one is limited so it cannot take memory your site needs.
  • A staging copy never runs the worker: its database is a copy of your live one, and it would run your pending jobs a second time.

Setting Worker to Off stops the workers once they finish the job in hand. If you prefer to work through the queue on a schedule instead, add a scheduled task: Schedule * * * * *, Command php artisan queue:work --stop-when-empty --max-time=50.

When something breaks

  • The Logs tab shows PHP and nginx errors (Site logs). Laravel's own log is in storage/logs.
  • A failed deploy leaves the live site as it was; the deploy log names the step that failed.
  • Change the PHP version under Configure → PHP version (Switching PHP versions).

Stuck? Contact support — replies within one business day.