Loading...

This is taking longer than expected.

Back to the help centre

Get it running

From a fresh clone to the application open in your browser, signed in as admin.

This guide takes you from a clone of the repository to the application running on your machine and you signed in as an administrator. You need it once per machine.

What you need installed

Requirement Version Why
PHP 8.2 or newer composer.json requires ^8.2
Composer 2 installs the PHP dependencies
Node.js and npm Node 20.19 or newer, or 22.12 or newer the assets are built with Vite 7
A database MySQL 8, MariaDB, PostgreSQL or SQLite config/database.php also carries a SQL Server connection

Redis and Memcached are optional. The default queue, cache and session drivers are all database, so nothing else has to be running.

The seven steps

Run them from the root of the clone, in this order.

1. Copy the environment file.

cp .env.example .env

2. Install the PHP dependencies.

composer install

Besides installing packages, this points core.hooksPath at scripts/git-hooks, so a pre-push hook runs from now on. It stops a push when a help guide the push changes is missing its translation; work you have not committed does not count, and git push --no-verify skips it once.

3. Generate the application key.

php artisan key:generate

4. Point .env at your database. The block depends on the engine; see the next section. Create the database first: the migration does not create it.

5. Run the migrations and the seeders.

php artisan migrate --seed

6. Install the frontend dependencies and build the assets.

npm ci && npm run build

7. Link the public storage folder.

php artisan storage:link

The database block of .env

.env.example ships with MySQL. Replace the block with the one for your engine.

MySQL or MariaDB:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_project
DB_USERNAME=root
DB_PASSWORD=

For MariaDB set DB_CONNECTION=mariadb; the other variables are the same.

PostgreSQL:

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=your_project
DB_USERNAME=postgres
DB_PASSWORD=

SQLite needs no server. Create the file and name it:

touch database/database.sqlite
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/your-project/database/database.sqlite

If you remove DB_DATABASE altogether, the sqlite connection falls back to database/database.sqlite inside the project. Leaving the MySQL value laravel in place would make SQLite look for a file called laravel, so remove it or replace it.

All engines also accept DB_URL as a single connection string instead of the separate host, port, database, username and password. The rest of the database variables are in The environment file.

Two variables to fix before the first page loads

.env.example is written for a server that has Amazon S3 and a transactional mailer. On a laptop, two of its values will break the first request or the first email.

Variable Shipped value Set it to
FILESYSTEM_DISK s3, with placeholder AWS keys public until you have a bucket
MAIL_MAILER failover, which tries Mailgun then Amazon SES log to write emails to the log, or smtp with a local catcher

Also set APP_URL to the address you will actually open. The example value is http://weblabor-base.test, which only resolves if Herd or Valet is serving the folder under that name.

What the seed creates

php artisan migrate --seed runs DatabaseSeeder, which calls five seeders in this order:

  1. PermissionSeeder reads every admin resource and creates a create, retrieve, update and delete permission for each one, plus anything you add to permissions in config/app.php. Permissions that no longer exist are deleted when allow_permisisons_deletion is true, which it is by default.
  2. RoleSeeder creates the role named in admin_role (admin) and gives it every permission, creates a role called client with none, and creates the default_role if you name one.
  3. AdminSeeder creates one administrator per email in sudo and assigns the admin role.
  4. UserSeeder creates one plain user per email in default_users, with no role.
  5. AddOnSeeder creates the add-ons listed in the file. The list ships empty and the seeder returns early when the billing package is not installed.

Both user seeders use firstOrCreate, so running the seed again never resets a password.

Your first sign-in

The accounts come from two arrays in config/app.php:

'sudo' => [
    '[email protected]',
],

'default_users' => [
    '[email protected]',
],

Put your own email in sudo before you seed. If you already seeded, add it and run php artisan db:seed --class=AdminSeeder; the seeder only creates what is missing.

For each email, both seeders do exactly this:

  • The name is the part before @ turned into words: CarlosEscobar becomes Carlos Escobar, admin becomes Admin.
  • The email is lowercased before it is saved, so you sign in with the lowercase form even if config/app.php has capitals.
  • The password is the lowercase part before @, reversed. [email protected] gets nimda; [email protected] gets tset; [email protected] gets rabocsesolrac.
  • The email is marked as verified, so the account skips verification.

AdminSeeder does one more thing: if the stored password still equals the generated one, it records a password change request. The first time that administrator signs in, the security middleware sends them to /password/request to choose a real password before they can reach anything else. default_users get no such request.

Whether an account is a super-administrator is not stored: the sudo attribute on the user compares the email against the lowercased sudo list every time. Removing an email from the array removes the privilege on the next request, although the account keeps the admin role until you take it away in the panel.

Open the site and go to /login. Sign-in accepts the email by default; the LOGIN_IDENTITIES variable widens it to phone and username. After signing in you land on /app, the value of home_route in config/app.php, and the admin panel is at /admin. Your own profile, devices and notifications are at /account; see Your account area.

The sign-in screen

Start the servers

composer dev

This runs four processes in one terminal: php artisan serve on port 8000, php artisan queue:listen --tries=1, php artisan pail tailing the log, and npm run dev for Vite with hot reload. Set APP_URL=http://localhost:8000 so the links the application builds match the address you open.

If you serve the folder with Herd, Valet or your own web server, you only need Vite:

npm run dev

Or skip Vite entirely and use the assets you built in step 6.

Everything optional starts off

Plans, add-ons, announcements, referrals and tracking each have a flag in config/features.php, and every flag defaults to false. A disabled feature loses its routes and its menu entries, admin panel included. If the panel is missing a section you expected, that is why. The PIN, phone verification, the PWA, web push, Stripe and the AI translator each also wait for their own variables. Configure your project lists the flags and where each one leads.

When it does not start

What you see Cause Fix
No application encryption key has been specified step 3 was skipped php artisan key:generate
Connection refused or Unknown database the server is down or the database does not exist start the server and create the database named in DB_DATABASE
Database file at path [laravel] does not exist SQLite with the MySQL DB_DATABASE still in place remove DB_DATABASE or point it at the .sqlite file
Unable to locate file in Vite manifest the assets were never built npm run build, or keep npm run dev running
An error mentioning InvalidAccessKeyId or S3 on upload FILESYSTEM_DISK=s3 with the placeholder keys FILESYSTEM_DISK=public
A verification email never arrives MAIL_MAILER=failover with no Mailgun or SES credentials MAIL_MAILER=log and read storage/logs/laravel.log
No admin role defined. during the seed admin_role in config/app.php is empty give it a name; admin is the default
A permission you just created is denied Spatie caches permissions for 24 hours php artisan permission:cache-reset
Images under /storage/... return 404 step 7 was skipped php artisan storage:link
Vite refuses to start or reports a syntax error Node older than 20.19 upgrade Node
A setting you changed is ignored a cached configuration php artisan config:clear

The daily commands, the tests and the checks that run before a push are in Working on the code.