hpatoio/deploy-bundle
hpatoio/deploy-bundle is a Symfony bundle that simplifies deploying PHP applications with configurable deployment tasks, release management, and repeatable, automation-friendly production releases.
This is a Symfony 2 bundle (not a Laravel package), so a Laravel developer should treat it as a reference implementation of the old project:deploy task rather than a drop-in dependency. Day-to-day, you install it, point it at one or more servers, and let it rsync your working tree over SSH.
Minimal steps:
composer require hpatoio/deploy-bundle
app/AppKernel.php:
new Hpatoio\DeployBundle\DeployBundle(),
app/config/config.yml (or a dedicated deploy.yml imported from it):
deploy:
servers:
staging:
host: staging.example.com
port: 22
user: deploy
dir: /var/www/app/current
exclude:
- .git
- app/cache
- app/logs
- var
- web/uploads
app/console list | grep -i deploy
app/console <deploy-command> staging
Where to look first:
Command/ directory — that is the actual contract (command name, options, how the rsync/ssh command line is assembled).DependencyInjection/Configuration.php — this is the definitive schema for the YAML above; do not trust blog posts from 2014.Configuration.php to see which keys actually exist.First real use case: deploy a staging branch to a single host where you control both the build machine and the target user. That is the happy path this bundle was built for. Add a second server entry only once staging is green.
If you are on Laravel today, the pragmatic play is to read the command source and port the rsync invocation into an Artisan command or an Envoy task; the configuration shape below transfers almost unchanged.
One config block per environment. Keep staging, production, and any per-client targets as sibling keys under servers. Pass the server name as the command argument so the same CI job can target different hosts via a parameter rather than a code change.
Deploy from CI, not from a laptop. The command shells out to rsync/ssh, so the only requirements on the runner are those binaries plus an SSH key with access to the target. A typical job:
composer install --no-dev --optimize-autoloader
app/console <deploy-command> production
# then a separate ssh step for cache/migrations
ssh deploy@prod 'cd /var/www/app/current && app/console cache:clear --env=prod'
Explicit excludes are the integration point. The exclude list is the main knob you will edit repeatedly. At minimum exclude VCS metadata, framework cache/log dirs, local .env/parameters.yml, user uploads, and any node_modules-style build artifacts. Getting this list right is most of the operational quality of the deploy.
Pair the sync with a remote step. This bundle copies files; it does not run migrations or clear caches on the target. The standard pattern is two commands: rsync, then a short SSH script (or a second Symfony command) that clears cache, runs migrations, and warms up. Keep that second step idempotent.
Extension point: wrap, don't fork. Register your own console command that calls the deploy command's service or reuses its rsync string builder, then appends your post-deploy logic. That keeps the vendor bundle untouched when you eventually replace it.
Laravel translation. In an Artisan command, the equivalent body is a Process::run(sprintf('rsync -az --delete %s %s@%s:%s', ...)) with an exclude array from config/deploy.php. Mirror the YAML shape so operators recognize it.
Configuration tree changes) and on newer PHP versions. Read the bundle's composer.json constraints before assuming it installs.%kernel.root_dir%-style tokens or $VAR fragments inside dir, host, or exclude entries), pin to 1.5.3+ and re-test your existing config — interpolated values that silently passed through unresolved on older tags may now expand, or vice versa. If you had worked around broken interpolation by hardcoding absolute paths, revisit those workarounds before upgrading.--delete is a footgun. If the rsync builder uses --delete, an over-broad exclude list or a wrong dir will wipe server-side files (uploads, generated assets). Verify exactly which flags are emitted before the first production run; do a dry run (--dry-run) if the command exposes or forwards extra rsync options.parameters.yml/.env must already exist on the server. Document that in the runbook.www-data, cache and log dirs will break on the first request. Add a chmod/chown step, or ensure the deploy user is in the web group with setgid directories.sshpass). Prefer key-based auth, and confirm from the command source whether a password path exists at all before putting one in config.config.yml, clear the Symfony cache (app/console cache:clear) or your new server keys will silently not appear. This also masks interpolation fixes: an old compiled container can make a 1.5.3 upgrade look like a no-op.$process->getExitCode() and wire the command into CI so a non-zero status fails the build.vendor/ if you composer install on the target instead of syncing it.~1.5.3 constraint), keep the rsync invocation isolated behind your own command, and have a migration path to Deployer or a Laravel-native Artisan/Envoy command ready.How can I help you explore Laravel packages today?