laravel-ftp-deploy maintained by meghdadfadaee
Laravel FTP Deploy
Deploy changed Laravel project files over FTP using a SamKirkland-compatible sync-state manifest.
Installation
composer require meghdadfadaee/laravel-ftp-deploy
The package registers itself through Laravel package discovery.
Configuration
Add an FTP deploy disk to config/filesystems.php:
'ftp_deploy' => [
'driver' => 'ftp',
'host' => env('FTP_DEPLOY_HOST'),
'username' => env('FTP_DEPLOY_USERNAME'),
'password' => env('FTP_DEPLOY_PASSWORD'),
'port' => (int) env('FTP_DEPLOY_PORT', 21),
'root' => env('FTP_DEPLOY_ROOT'),
'passive' => env('FTP_DEPLOY_PASSIVE', true),
'ssl' => env('FTP_DEPLOY_SSL', false),
'timeout' => (int) env('FTP_DEPLOY_TIMEOUT', 30),
'throw' => true,
'report' => false,
],
Customize deploy behavior in config/services.php:
'ftp_deploy' => [
'disk' => env('FTP_DEPLOY_DISK', 'ftp_deploy'),
'local_root' => env('FTP_DEPLOY_LOCAL_ROOT', base_path()),
'state_path' => env('FTP_DEPLOY_STATE_PATH', 'storage/app/.ftp-deploy-sync-state.json'),
'api_token' => env('FTP_DEPLOY_API_TOKEN'),
'api_url' => env('FTP_DEPLOY_API_URL'),
'api_timeout' => (int) env('FTP_DEPLOY_API_TIMEOUT', 30),
'route' => [
'enabled' => env('FTP_DEPLOY_ROUTE_ENABLED', true),
'path' => env('FTP_DEPLOY_ROUTE_PATH', 'ftp/generate-sync-state'),
'name' => env('FTP_DEPLOY_ROUTE_NAME', 'ftp-deploy.generate-sync-state'),
'middleware' => ['api'],
],
'exclude' => array_filter(array_map('trim', explode(',', env(
'FTP_DEPLOY_EXCLUDE',
'.git,.idea,.vscode,.env,node_modules,storage/logs,storage/framework/cache,storage/framework/sessions,storage/framework/views,storage/app/.ftp-deploy-sync-state.json,.ftp-deploy-sync-state.json',
)))),
],
Useful environment keys:
FTP_DEPLOY_HOST=
FTP_DEPLOY_USERNAME=
FTP_DEPLOY_PASSWORD=
FTP_DEPLOY_PORT=21
FTP_DEPLOY_ROOT=
FTP_DEPLOY_PASSIVE=true
FTP_DEPLOY_SSL=false
FTP_DEPLOY_TIMEOUT=30
FTP_DEPLOY_DISK=ftp_deploy
FTP_DEPLOY_STATE_PATH=storage/app/.ftp-deploy-sync-state.json
FTP_DEPLOY_API_TOKEN=
FTP_DEPLOY_API_URL=
FTP_DEPLOY_API_TIMEOUT=30
Commands
Preview changed files:
php artisan ftp:deploy --dry-run
Upload changed files and update the remote sync-state:
php artisan ftp:deploy --yes
Refresh the remote server sync-state through the JSON API before deploying:
php artisan ftp:deploy --refresh-remote-state --yes
This option calls the same API implementation used by ftp:api-summary, then continues the FTP deploy using the refreshed remote state file.
Generate a sync-state file locally:
php artisan ftp:generate-sync-state --output=storage/app/.ftp-deploy-sync-state.json
Call the JSON API and print a summary:
php artisan ftp:api-summary https://example.com/ftp/generate-sync-state --token=your-token
If FTP_DEPLOY_API_URL and FTP_DEPLOY_API_TOKEN are configured, the command can be run without arguments:
php artisan ftp:api-summary
Extra excludes may be passed as repeated options or comma-separated values:
php artisan ftp:deploy --exclude=vendor --exclude="*.map" --yes
JSON API
The package registers GET /ftp/generate-sync-state by default. It requires either:
Authorization: Bearer your-token
or:
X-Ftp-Deploy-Token: your-token
The route generates the current sync-state, persists it to services.ftp_deploy.state_path, and returns JSON with summary metadata and the full state payload.