Skip to content

Installation

Reshape is a monorepo containing two applications you will run side by side: the Laravel API in api/ and the Vue frontend in web/. This page walks you through installing both, configuring your environment, and setting up the local reshape.test domains with HTTPS.

Requirements

Before installing Reshape, make sure your machine has:

  • PHP 8.5+ with the usual Laravel extensions
  • Composer
  • Node.js 18+ and npm
  • SQLite (the default local database — MySQL and PostgreSQL work too)

Media Library Pro

Reshape uses Spatie Media Library Pro, which is installed from Spatie's private Composer registry. You need a license and credentials for satis.spatie.be — add them once with:

bash
composer config http-basic.satis.spatie.be <your-email> <your-license-key>

Installing the API

Clone the repository, then run the setup script from the api/ directory:

bash
cd api
composer setup

The setup script (defined in composer.json) does the heavy lifting for you:

  1. composer install
  2. Copies .env.example to .env (if one doesn't exist)
  3. php artisan key:generate
  4. php artisan migrate --force
  5. npm install && npm run build (assets for the Filament admin panel)

Preparing reference data

Reshape ships with a db:prepare command that seeds everything the application needs to function — the permission catalog, roles, reaction types, countries, currencies, timezones, industries, contact methods, default themes, and plans:

bash
php artisan db:prepare

Don't skip this step

Roles and permissions are database records. Until db:prepare has run, no user can be assigned a role and most authorization checks will fail.

Demo data (optional)

If you'd like something to look at, seed the demo dataset — 25 companies with contacts, addresses, customers, and announcements, plus three ready-made accounts:

bash
php artisan db:seed
EmailRole
super_administrator@reshape.testSuper Administrator
administrator@reshape.testAdministrator
user@reshape.testSuper Administrator

Since login is passwordless, you sign in to these accounts with a one-time code — with the default MAIL_MAILER=log the code is written to the Laravel log. See Development for the shortcut.

Installing the frontend

bash
cd web
npm install
cp .env.example .env

The frontend's .env points at the API and defines which login options are shown:

ini
VITE_BACKEND_URL=https://api.reshape.test
VITE_FRONTEND_URL=https://reshape.test

REVERB_APP_KEY=<same value as the API's REVERB_APP_KEY>
REVERB_HOST=api.reshape.test
REVERB_PORT=443
REVERB_SCHEME=https

# Show/hide social login buttons
VITE_OAUTH_GOOGLE=false
VITE_OAUTH_GITHUB=false
VITE_OAUTH_LINKEDIN=false

Environment configuration

The API's .env works out of the box with SQLite and the log mailer, but a few values deserve attention:

VariableWhat to set it to
APP_URLhttps://api.reshape.test
FRONTEND_URLhttps://reshape.test — used for CORS, redirects, and invitation links
REVERB_APP_KEY / REVERB_APP_SECRETAny random strings (e.g. openssl rand -hex 32); the key must match the frontend's REVERB_APP_KEY
MAIL_MAILERlog for local development, or point it at Mailpit/SMTP to receive real emails
AUTO_LOGIN_USER_EMAILOptional development helper — see Development

One .env gotcha

.env.example defines FRONTEND_URL twice; the later http://localhost value wins. Make sure the effective value is https://reshape.test once you've set up local domains below.

Stripe

Billing uses Laravel Cashier. The Stripe keys are not present in .env.example, so add them yourself when you're ready to work on billing:

ini
STRIPE_KEY=pk_test_...
STRIPE_SECRET=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

OAuth providers

To enable social login, create OAuth apps with each provider and fill in the credentials:

ini
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=

Then flip the matching VITE_OAUTH_* flags to true in web/.env so the buttons appear on the login page. The callback URL for each provider is https://reshape.test/oauth/callback/{provider}. See Authentication for details.

Local domains & HTTPS

Reshape's defaults assume the frontend lives at https://reshape.test and the API at https://api.reshape.test. Real domains and real HTTPS locally mean cookies, CORS, Sanctum, and websockets behave exactly like production — no localhost:3000 special cases.

The setup uses three small tools, adapted from this excellent write-up by François Liger:

  1. DNS — resolve *.test to your machine
  2. mkcert — generate locally-trusted TLS certificates
  3. Caddy — terminate HTTPS and proxy to your dev servers

macOS shortcut

If you use Laravel Herd, it already resolves *.test and can serve the API directly — cd api && herd link api.reshape && herd secure. You still need Caddy (or Herd's proxy feature) for the frontend on port 3000. The instructions below are the fully cross-platform path.

1. Point .test at your machine

bash
brew install dnsmasq

# Resolve every .test domain to localhost
echo 'address=/test/127.0.0.1' >> "$(brew --prefix)/etc/dnsmasq.d/test.conf"

# Tell macOS to use dnsmasq for the .test TLD
sudo mkdir -p /etc/resolver
echo 'nameserver 127.0.0.1' | sudo tee /etc/resolver/test

sudo brew services start dnsmasq
bash
sudo apt install dnsmasq   # or your distro's package manager

# Resolve every .test domain to localhost
echo 'address=/test/127.0.0.1' | sudo tee /etc/dnsmasq.d/test.conf
sudo systemctl restart dnsmasq
text
Windows has no practical dnsmasq equivalent, so use the hosts file
instead. Open an elevated editor and add these lines to
C:\Windows\System32\drivers\etc\hosts:

127.0.0.1 reshape.test
127.0.0.1 api.reshape.test

The simple fallback

Reshape only needs two fixed hostnames, so the hosts-file approach shown for Windows works on macOS and Linux too (/etc/hosts). dnsmasq is only required if you want wildcard .test resolution — handy once you start adding more subdomains.

systemd-resolved

On Ubuntu-flavoured distros, systemd-resolved already listens on port 53. Either disable its stub listener (DNSStubListener=no in /etc/systemd/resolved.conf) or simply use the hosts-file fallback.

2. Generate trusted certificates

Install mkcert (brew install mkcert / apt install mkcert / choco install mkcert), then:

bash
mkcert -install
mkdir -p ~/certs && cd ~/certs
mkcert "reshape.test" "*.reshape.test"

This produces reshape.test+1.pem and reshape.test+1-key.pem, trusted by your browser because mkcert -install added a local CA to your system trust store.

3. Proxy with Caddy

Install Caddy (brew install caddy / apt install caddy / choco install caddy) and use this Caddyfile — on macOS at $(brew --prefix)/etc/Caddyfile, on Linux at /etc/caddy/Caddyfile:

text
reshape.test {
	tls /Users/you/certs/reshape.test+1.pem /Users/you/certs/reshape.test+1-key.pem
	reverse_proxy localhost:3000
}

api.reshape.test {
	tls /Users/you/certs/reshape.test+1.pem /Users/you/certs/reshape.test+1-key.pem

	# Reverb websockets
	@reverb path /app/* /apps/*
	reverse_proxy @reverb localhost:9000

	reverse_proxy localhost:8000
}

The @reverb matcher routes websocket traffic (/app/...) to the Reverb server on port 9000 while everything else goes to php artisan serve on port 8000 — which is why the frontend's .env can point Echo at api.reshape.test:443 over HTTPS.

Start Caddy:

bash
brew services start caddy
bash
sudo systemctl enable --now caddy
bash
caddy run --config C:\path\to\Caddyfile

Verify

With both dev servers running (see Development), you should now be able to open:

  • https://reshape.test — the frontend, with a padlock
  • https://api.reshape.test/up — the API health check

The login page served over local HTTPS

Next steps

Head over to Development to start the dev servers, log in, and learn the day-to-day workflow.