perspikapps / php-easy-deployer
A deployer.org recipe with url-based easy configuration
Requires
- php: ^7.4
- deployer/deployer: 7.0.*@dev
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- nunomaduro/phpinsights: dev-master
- orchestra/testbench: ~5 || ~6
- phpunit/phpunit: ^9.0
- squizlabs/php_codesniffer: ^3.5
This package is not auto-updated.
Last update: 2026-08-08 18:07:24 UTC
README
Easy Deployer
This package handles deployement configuration via a deploy.yaml file to define deploy strategy and a .hostmap file to define target strategy
Installation
Install via composer
composer require perspikapps/klick-deploy
Usage
Deployment is handled by deployphp/deployer package.
deploy.yaml
See deployer config for details
import: - vendor/perspikapps/klick-deploy/src/strategy_laravel.php - vendor/perspikapps/klick-deploy/src/strategy_upload.php - vendor/perspikapps/klick-deploy/src/strategy_update.php - vendor/perspikapps/klick-deploy/src/strategy_shared.php - vendor/perspikapps/klick-deploy/src/strategy.php config: source_path: './' shared_dirs: - storage shared_files: - .env writable_dirs: - bootstrap/cache - storage - storage/app - storage/app/public - storage/framework - storage/framework/cache - storage/framework/sessions - storage/framework/views - storage/logs log_files: - storage/logs/*.log hosts: example.com: hostname: ssh.example.com labels: env: production secrets: APP_KEY: ENCRYPTED_APP_KEY DB_PASSWORD: ENCRYPTED_DB_PASSWORD MAIL_PASSWORD:
Host entries may define a secrets map. Each key is the environment variable name that should be written to the remote .env file.
Supported value formats are:
APP_KEY: %APP_KEY%uses the current process environment variableAPP_KEYwithout decryption.APP_KEY: ENCRYPTED_APP_KEYdecrypts the inline value remotely with thedecrypthelper.APP_KEY: { secret: ENCRYPTED_APP_KEY, env: APP_KEY }uses explicit encrypted value with optional env fallback whensecretis empty.
This keeps secret values out of the repository while still letting each host declare exactly which secrets it needs.
.hostname
Specify ONE deployement target per line as url:
- url scheme = strategies to activate (
+separated, each must be loaded inimportsection ofdeploy.yamlfile) - url user/host/port = server to deploy to
- url path = path on server to deploy to
- url query = deploy options to use
- url anchor = variables to set in .env file after deployment
upload+laravel://user@dev.exemple.com/var/home/{{hostname}}?bin/php=/opt/plesk/php/7.4/bin/php&writable_mode=chmod#debug=true&env=staging
upload+laravel://user@beta.exemple.com/var/home/{{hostname}}?bin/php=/opt/plesk/php/7.4/bin/php&writable_mode=chmod#debug=true&env=beta
upload+laravel://user@www.exemple.com/var/home/{{hostname}}?bin/php=/opt/plesk/php/7.4/bin/php&writable_mode=chmod#debug=false&env=production
Features
Per-Branch Preview Deployments
Passing --branch-scope=<branch-name> to dep deploy (or the branch-scope input on the actions/deploy/actions/run-deployer GitHub Actions) derives an isolated alias, deploy_path, and database name for that branch, so concurrent branches deployed against the same host template never collide. This is wired up automatically once a pull request is ready for review: .github/workflows/deploy.yml's ready_for_review/synchronize triggers pass the PR's head branch as the scope, so every PR gets its own preview subdomain (e.g. taskadabra-alpha.perspikapps.fr + branch feature/foo-bar → taskadabra-alpha-feature-fo-c6c1d9.perspikapps.fr) instead of sharing one "alpha" host.
Requirements: the host's alias must be a subdomain (e.g. app-alpha.example.com, not a bare root domain) so a sibling subdomain label can be derived.
Corresponding cleanup runs via dep cpanel:teardown --branch-scope=<branch-name> (the actions/teardown GitHub Action), triggered by .github/workflows/deploy-teardown.yml on pull_request: closed. It removes the subdomain, database + user, mail account, and deploy_path directory for that branch. Teardown refuses to run without --branch-scope, so it can never be pointed at a real (non-preview) host, and tolerates resources that are already missing.
After a successful dep deploy, the deploy:report_url task prints the final https://<alias> URL for CI to pick up. actions/run-deployer exposes it as a deploy-url output (bubbled up through actions/deploy), and .github/workflows/deploy.yml uses it to create or update a PR comment (via the generic tomgrv/actions/create-pr-comment action, keyed per host) linking straight to the deployed preview — re-deploys of the same host update the same comment instead of piling up duplicates.
Execution Plan Hash Verification
Before the deploy lock is acquired, deploy:lock's before hook computes a SHA-256 hash of the exact ordered list of tasks Deployer's ScriptManager resolves for the deploy command (including before/after hooks) and compares it against an optional deploy_plan_hash value — settable globally under deploy.yml's top-level config: block, or per host alongside deploy_path/remote_user:
config: deploy_plan_hash: '3f2a9c...' # sha256 of the resolved `deploy` task pipeline
- Hash configured and mismatched: the plan about to run, its computed hash, and the configured hash are logged, and the deploy aborts before locking — this catches the deploy task pipeline silently drifting from what was reviewed (a recipe or dependency update reordering/adding tasks).
- Hash configured and matching: the deploy proceeds normally.
- No
deploy_plan_hashconfigured: the check is purely informative — it logs the computed hash and never blocks the deploy.
GitHub Actions Manual Dispatch
deploy.yml also accepts workflow_dispatch with environment, branch-scope, and selector inputs, so a deployment for an arbitrary branch can be triggered on demand (including via the MCP server's trigger_deploy tool — see below) without needing to push to main/release/* or request a PR review.
MCP Server & Skill
mcp/ ships a Model Context Protocol server (see mcp/README.md) so an AI agent can inspect deploy.yml, resolve which environment a branch maps to, preview what a per-branch preview deployment would be named, and — with a GitHub token — trigger and monitor a real deployment. A companion Claude Code skill (klick-deploy, in this monorepo at .agents/skills/klick-deploy/SKILL.md) documents how to use them together.
PHP/Composer Setup via tomgrv/actions
actions/run-deployer (and .github/workflows/deploy.yml's pre-build step) delegate PHP version/extension detection, shivammathur/setup-php, and ramsey/composer-install to tomgrv/actions/setup-php rather than reimplementing that logic. run-deployer calls it unconditionally, so it never assumes the caller already prepared PHP — a package consumer can invoke actions/deploy/actions/unlock/actions/teardown directly with no setup step of their own.
Automatic Crontab Setup
The package automatically configures essential Laravel cron jobs during deployment:
- Queue Restart:
php artisan queue:restartruns every hour to prevent memory leaks - Schedule Runner:
php artisan schedule:runruns every minute to execute Laravel's task scheduler
These cron jobs are automatically set up just before the deployment unlock phase and use the deployment path to ensure they point to the current release.
Security
If you discover any security related issues, please email instead of using the issue tracker.