Stefan Lazic 16c6c28f07
CI / ci (push) Canceled after 0s
Login Loop
2026-09-05 09:24:09 +01:00
2026-08-02 17:47:23 +01:00
2026-08-02 17:47:23 +01:00
2026-08-07 17:30:12 +01:00
2026-08-02 17:47:23 +01:00
2026-09-05 09:24:09 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 08:36:54 +01:00
2026-08-05 09:25:59 +01:00
2026-08-07 17:30:12 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 09:24:09 +01:00
2026-09-05 08:36:54 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 09:11:24 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:36:54 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:36:54 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 08:21:33 +01:00
2026-09-05 09:24:09 +01:00
2026-08-02 17:47:23 +01:00
2026-09-05 08:21:33 +01:00

NextChair

NextChair is a multi-tenant, white-label booking platform for barbershops. The application is being rebuilt as a conventional Laravel web application using PHP, MySQL, Blade, Tailwind CSS, Alpine.js, and Vite.

The audited Next.js implementation is preserved in legacy-nextjs as the functional and visual migration reference. The Laravel application has its own deployment-neutral Docker option at the repository root; files inside legacy-nextjs are not used by it.

Local development

composer install
cp .env.example .env
php artisan key:generate
npm install
npm run build
php artisan serve

Configure the MySQL connection in .env before running migrations. The application resolves a business only from the request hostname through the business_domains table; it never guesses a tenant from the first business in the database. For local multi-tenant work, map each configured hostname to 127.0.0.1 in /etc/hosts.

Platform and tenant setup

Migrations create schema only. They do not create a demo business or a business owner. After migrating, open /install once and create the platform administrator. That account can sign in at /manager/sign-in, create businesses, edit their primary domains, and share the one-time owner setup link generated during provisioning.

For an existing installation created before this platform/tenant split, the recorded initialAdminUserId account is allowed to sign in once and is promoted to the platform administrator. No other business owner can use that upgrade path.

Business provisioning creates the tenant domain, settings, booking rules, opening hours, system roles, owner staff profile, and seven-day owner invitation in one transaction. The owner chooses a password through that invitation; platform administrators and business owners are separate account types.

If demo data is useful for local development, opt into the existing seeder explicitly:

NEXTCHAIR_SEED_DEMO=true php artisan db:seed

Docker deployment

The root compose.yaml runs Laravel with PHP 8.4 FPM, Nginx, MySQL 8, the database-backed queue worker, and the scheduler. It does not include or configure Caddy; an existing reverse proxy can forward traffic to Nginx on 127.0.0.1:8085.

First run:

cp .env.example .env

Set private values in .env, including:

APP_URL=http://localhost:8085
APP_KEY=
DB_HOST=db
DB_DATABASE=nextchair
DB_USERNAME=nextchair
DB_PASSWORD=replace-with-a-private-password
DB_ROOT_PASSWORD=replace-with-a-private-root-password

Then build and start the stack:

docker compose build
docker compose up -d
docker compose exec app php artisan key:generate
docker compose exec app php artisan migrate

Then visit http://localhost:8085/install to create the first platform administrator. Do not run migrations or create tenants from container startup; the tenant owner is provisioned manually from Manager.

Migrations are intentionally not run by container startup. To inspect the application logs:

docker compose logs -f app nginx queue scheduler db

The default host binding is 127.0.0.1:8085:80. Override it with NEXTCHAIR_HTTP_BIND and NEXTCHAIR_HTTP_PORT in .env when needed. MySQL has no published host port and is reachable only as db:3306 inside Compose.

Verification

php artisan test
npm run build
S
Description
Booking app as an alternative to Booksy
Readme
2.6 MiB
0 Stars 1 Watchers 0 Forks
Languages
TypeScript 89.4%
HTML 9.6%
CSS 0.3%
JavaScript 0.3%
Dockerfile 0.2%
Other 0.2%