axazara / bankai
A Laravel Envoy deployment package for streamlined and consistent deployment processes across projects.
Requires
- php: ^8.1
- laravel/envoy: ^2.0
Requires (Dev)
- axazara/php-cs: ^0.3
- illuminate/contracts: ^10.0 || ^11.0 || ^12.0 || ^13.0
- larastan/larastan: ^2.9 || ^3.0
- nunomaduro/collision: ^7.0 || ^8.0
- orchestra/testbench: ^8.0 || ^9.0 || ^10.0 || ^11.0
- phpstan/extension-installer: ^1.3
- phpstan/phpstan-deprecation-rules: ^1.1 || ^2.0
- phpstan/phpstan-phpunit: ^1.3 || ^2.0
- phpunit/phpunit: ^10.5 || ^11.0
- spatie/laravel-ray: ^1.32
This package is auto-updated.
Last update: 2026-07-26 18:56:38 UTC
README
Bankai offers a streamlined solution for achieving zero-downtime deployments in Laravel applications using Envoy. This guide covers installation, configuration, and deployment, complete with examples and detailed explanations.
Requirements
- PHP 8.1 or higher
- Laravel 10.x, 11.x, 12.x or 13.x
Installation
Begin by integrating Bankai with your Laravel project via Composer:
composer require axazara/bankai --dev
Configuration
After installation, initialize Bankai with the following command:
php artisan bankai:install
This will:
- Publish
config/bankai.phpin your config directory. - Add
Envoy.blade.phpto your project's root.
Customize config/bankai.php according to your project's needs.
Example configuration (config/bankai.php)
return [ // General deployment settings 'settings' => [ // Git repository to deploy (clone strategy only). Use an SSH URL with a // read-only deploy key. HTTPS URLs with embedded credentials are rejected; // CI can inject an ephemeral token-bearing URL through the // BANKAI_REPOSITORY_URL environment variable instead. 'repository_url' => 'git@github.com:your-org/your-repository.git', // Slack Incoming Webhook URL; leave null to disable notifications 'slack_webhook_url' => env('BANKAI_SLACK_WEBHOOK_URL'), // How many releases to keep on the server (the live one included) 'releases_to_keep' => 3, ], // Define your environments, e.g. staging and production 'environments' => [ 'staging' => [ 'strategy' => 'artifact', // 'artifact' or 'clone', see below 'ssh_host' => 'your-host', // SSH host of the server 'ssh_user' => 'your-user', // SSH user used for deployment 'url' => 'https://staging.your-app.com', // Application URL 'branch' => 'main', // Branch to deploy 'path' => '/var/www/your-app', // Deployment directory on the server 'php' => 'php', // PHP binary 'composer' => 'composer', // Composer binary 'composer_options' => '', // Extra options passed to `composer install` 'migration' => false, // Run migrations 'seeder' => false, // Run seeders 'maintenance' => false, // Toggle maintenance mode during deploy 'octane' => [ 'install' => false, // Install Laravel Octane 'reload' => false, // Reload Octane after deploy 'server' => 'swoole', // roadrunner, swoole, frankenphp or openswoole ], 'horizon' => [ 'terminate' => true, // Terminate Horizon after deploy ], 'queue' => [ 'restart' => false, // Restart queue workers after deploy ], ], ], ];
Example Envoy.blade.php
bankai:install generates this file for you. The Laravel bootstrap is handled by
AxaZara\Bankai\Bankai::bootstrap(), so your Envoy script stays to the point:
@include('vendor/autoload.php') @setup try { extract(AxaZara\Bankai\Bankai::bootstrap($env)); } catch (Throwable $e) { echo $e->getMessage(); exit(1); } @endsetup @import('vendor/axazara/bankai/src/Envoy.blade.php') @task("run:before_deploy") # Runs before the deployment starts (the new release is not cloned yet). true @endtask @task("run:after_deploy") cd "{{ $releasePath }}" # Your post-build commands here, e.g. php artisan jwt:secret --force @endtask @task("run:after_rollback") cd "{{ $currentReleasePath }}" @endtask
Deployment strategies
Bankai supports two ways of getting a release onto the server, selected per
environment with the strategy key.
artifact (recommended)
The machine running Envoy (CI or your laptop) builds the release and uploads a tarball; the server only extracts it. The server needs no Git access, no Composer authentication and no GitHub or registry credentials, and what was tested in CI is exactly what ships.
Everything happens inside one command:
vendor/bin/envoy run deploy --env=production
Right before extraction, Bankai copies the project to a temporary build
directory (excluding .git, .github, node_modules, tests, storage,
.env*, auth.json and the local vendor), runs
composer install --no-dev --optimize-autoloader, builds front-end assets when
a package.json with a build script is present, packs the tarball, uploads
it to {path}/artifacts/incoming.tar.gz over SSH, and the server consumes
(deletes) it after extraction. Your working directory is never modified.
php artisan bankai:artifact is also available to package the working
directory as-is (same exclusions), for inspection or manual distribution.
clone (default)
The historical flow: the server clones the repository and runs
composer install itself. Requires:
- an SSH
repository_urlwith a read-only deploy key installed on the server; - a
shared/auth.jsonon the server when private Composer packages are used.
For a temporary token-based clone (for example a GitHub App installation token
minted in CI), set the BANKAI_REPOSITORY_URL environment variable on the
machine running Envoy; it takes precedence over the configured URL and is never
stored on the server.
Deployment
The first deployment follows five steps. Once set up, day-to-day deployments are just Step 4.
Step 1 — Prepare the deployment directories
Set up your deployment environment:
vendor/bin/envoy run setup --env={your-environment}
This creates the directory structure on the server:
- releases/: Houses every deployment.
- shared/: Resources shared across releases, such as the
.envfile andauth.json. - backups/: Reserved for release backups.
- current: Symlink pointing to the live release.
Your application key is generated and stored in shared/.env.
This is a one-time setup, generally run from your local machine.
Step 2 — Configure your environment file
Edit the shared environment file created during setup. Every release symlinks to it:
{path}/shared/.env
Step 3 — Configure Composer authentication
Clone strategy only. With the artifact strategy the server never runs
Composer, so no credentials are needed there — skip this step entirely.
Required only if your application pulls private Composer packages or registries. Add an auth.json file to the shared directory:
{path}/shared/auth.json
Bankai symlinks shared/auth.json into each release before running composer install (during both setup and deploy), so Composer can authenticate. Because it lives in shared/, it is created once and reused by every release.
If your first setup already needs private packages, create the directory and the file beforehand so they exist when setup runs composer install:
mkdir -p {path}/shared && editor {path}/shared/auth.json
See the Composer authentication documentation for the expected file format.
Step 4 — Deploy
vendor/bin/envoy run deploy --env={your-environment}
This can be run from your local machine or from your CI/CD pipeline. At Axa Zara, we deploy automatically after each merge to the
stagingorreleasebranch.
Step 5 — Configure your web server
Point your web server at the current/public directory. For example, with Laravel Forge you should set your site's web directory to current/public. The current symlink always points to the latest release.
Lifecycle hooks
Bankai exposes three hooks you can define in your Envoy.blade.php:
run:before_deployruns before the new release is cloned.run:after_deployruns after the release is built, before it goes live.run:after_rollbackruns after a rollback completes.
Example:
@task("run:after_deploy") cd {{ $releasePath }} php artisan jwt:secret --force @endtask
The following variables are available in your tasks:
$releasePath— path to the release being deployed.$currentReleasePath— path to thecurrentsymlink (the live release).$sharedPath— path to the shared directory.$releasesPath— path to the releases directory.$php— path to the PHP binary.$composer— path to the Composer binary.
Rollback
Quickly revert to the previous release (atomic symlink switch, no maintenance window):
vendor/bin/envoy run deploy:rollback --env={your-environment}
Deployment lock
At the start of every deploy, Bankai atomically creates a lock directory on the
server ({path}/.bankai-deploy.lock). If the lock already exists, the deploy
aborts immediately with the timestamp of the run holding it. This guarantees two
deployments can never interleave: without it, two concurrent runs would race on
incoming.tar.gz, migrations and the current symlink.
The lock is released at the end of a successful deploy. It is deliberately not released on failure, because a half-finished deploy left the server in a state that deserves a human look. Once you have checked (and rolled back if needed), release it with:
vendor/bin/envoy run deploy:unlock --env={your-environment}
Additional commands
- Build a release artifact:
php artisan bankai:artifact - List releases (the live one is marked):
vendor/bin/envoy run releases --env={your-environment} - List backups:
vendor/bin/envoy run backups --env={your-environment}
Zero-downtime deployment mechanics
- New release preparation: Bankai creates a new release in the
releases/directory (cloned or extracted from the artifact). - Cache warm-up: The new release is optimised before going live; the live release's caches and the shared application cache store are never touched.
- Symlink switching: The
currentsymlink is switched atomically to the new release (ln + rename). - Health check: The application URL is polled (5 attempts) while the previous release is still on disk, so a failing release can be rolled back instantly.
- Cleanup: Old releases are pruned, keeping the live release and the most recent others (
releases_to_keep, default 3).
Sentry integration
Bankai can record a release in Sentry after each deployment. To enable it, add a
sentry block to config/bankai.php:
'sentry' => [ 'enabled' => false, 'organization' => 'your-organization', 'project' => 'your-project', 'token' => 'your-token', 'version' => null, // Defaults to the current release name when null ],
sentry.enabled: Set totrueto enable Sentry integration.sentry.organization: Your Sentry organization.sentry.project: Your Sentry project.sentry.token: Your Sentry auth token. Learn more here.sentry.version: The Sentry release version. Defaults to the current release name.
Contributing
Contributions are welcome.
Security vulnerabilities
If you discover a security vulnerability within this package, please email Axa Zara Security at security@axazara.com. All security vulnerabilities will be promptly addressed.
License
This project is open-sourced software licensed under the MIT license.