perspikapps/php-easy-deployer

A deployer.org recipe with url-based easy configuration

Maintainers

Package info

github.com/perspikapps/php-easy-deployer

Homepage

Issues

pkg:composer/perspikapps/php-easy-deployer

Transparency log

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.0 2022-05-23 19:36 UTC

README

Easy Deployer

Packagist Packagist Packagist

Commitizen friendly semantic-release

Buy me a coffee

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 variable APP_KEY without decryption.
  • APP_KEY: ENCRYPTED_APP_KEY decrypts the inline value remotely with the decrypt helper.
  • APP_KEY: { secret: ENCRYPTED_APP_KEY, env: APP_KEY } uses explicit encrypted value with optional env fallback when secret is 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 in import section of deploy.yaml file)
  • 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-bartaskadabra-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_hash configured: 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:restart runs every hour to prevent memory leaks
  • Schedule Runner: php artisan schedule:run runs 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.

Credits