- How do I install and set up orchestra/tenanti in a Laravel application?
- Install it with Composer, publish the package config, and define a tenant class that extends Orchestra\Tenanti\Tenant and implements getConnectionName() and getConfig(). Register that class under a driver key in the config and point the driver at a dedicated migration directory. From there you can run tenanti:migrate user --tenants=1,2 --pretend and confirm the generated SQL targets two distinct database names. The whole proof of concept is roughly a ten-minute spike; the remaining work is orchestration, not integration.
- Does orchestra/tenanti support database-per-tenant and schema-per-tenant isolation?
- Tenanti specializes Laravel's Migrator and DatabaseManager so the standard migrate, rollback, and seed commands can run against a named tenant connection selected at runtime. That model works for database-per-tenant and schema-per-tenant alike, provided your tenant driver resolves the correct connection name and config for each tenant. It does not fit a shared-schema design with a tenant_id discriminator, so commit to your isolation model before adopting the package. Schema-per-tenant semantics also diverge between MySQL and PostgreSQL, so validate your database engine early.
- Which Laravel versions does orchestra/tenanti support?
- The package listing does not establish its Laravel version support breadth, so check composer.json against your production major before writing code. Because Tenanti extends framework internals, a Laravel major upgrade can silently change connection resolution or migration batch semantics. Pin exact versions such as 6.3.*, commit the lockfile, and budget roughly half a day per Laravel major upgrade for validation.
- How do I run tenant migrations for a single tenant or all tenants at once?
- Tenanti exposes Artisan commands that run the migrate, rollback, and seed family against tenant connections, either for individual tenants or in bulk. A typical invocation is tenanti:migrate user --tenants=1,2, and --pretend emits the SQL without executing it. Use --pretend first to confirm your wiring targets the expected databases. Fan-out across many tenants is not transactional, so a failed wave can leave partial state and your tooling should be re-run oriented.
- How do I create a tenant driver and resolver with Tenanti?
- Define one class extending Orchestra\Tenanti\Tenant that implements getConnectionName() and getConfig(), then register it under a driver key in the package config. Point the driver at a dedicated tenant migration directory so tenant schema changes stay separate from your main application migrations. Tenanti assumes you bring your own tenant model and resolver; the package covers the schema plumbing around them rather than discovering tenants for you.
- Does Tenanti provide tenant-aware cache, queues, sessions, filesystems, or routing?
- No. Tenanti is deliberately narrow: it handles tenant-scoped database connections and migrations, plus the Artisan commands around them. Cache, filesystem, queue, session, routing, and tenant registries are not part of the package. Evaluate it as the migration half of a tenancy stack and plan to supply the rest yourself or through other packages. Queues in particular need explicit handling so workers do not fall back to the default connection.
- What are the production risks of running Tenanti with queue workers and scheduled commands?
- The most serious risk is a wrong-database write: queue workers, scheduled commands, and anything holding a stale connection instance can still use the default connection. Long-running workers also accumulate connection instances and can exhaust max_connections, and there is no built-in locking, so concurrent deploys can collide on the same tenant. Cheap mitigations include a middleware chokepoint with an assertion on the active connection name, DB::purge() at the end of each job, and per-tenant cache locks. Cross-tenant fan-out is not transactional, so design deploys to be safely re-runnable.
- How do I test tenant migrations in CI for a Laravel multi-tenancy setup?
- Stand up two ephemeral tenant databases and run migrate followed by rollback on every build against both of them. That harness catches the connection resolution and migration batch changes that a Laravel major upgrade can introduce silently. Pair it with a --pretend check that confirms SQL is emitted against two distinct database names. Keep the harness cheap and non-optional; it is your main defense against framework coupling.
- How does Tenanti automate provisioning when a new tenant is created?
- Orchestra\Tenanti\Observer hooks provisioning into tenant row creation, which is the right affordance for automated onboarding. When a tenant record is created, the observer can drive the connection setup and migration run for that tenant. You still own the tenant model, the resolver, and any post-provisioning steps such as seeding or queue configuration.
- Is orchestra/tenanti well maintained, and are there alternatives I should consider?
- It is a narrow, high-leverage package with zero dependents and thin maintenance, so plan for a fork contingency rather than hoping upstream keeps pace. Pin exact versions, commit your lockfile, and keep the CI harness in place so you can validate upgrades or take over maintenance. If you need a full tenancy stack with cache, filesystem, and queue isolation out of the box, compare it against broader tenancy packages before committing. The decision hinges on whether database-per-tenant or schema-per-tenant isolation is already a committed architectural choice.