Deploying Your App ================== Automating deployment moves your code from local development to a staging or production server in a consistent, repeatable way. LacePHP’s **Deploy** command wraps SSH, Git, and custom hooks into a single workflow—so you never miss a step. Why Deployment Automation Matters --------------------------------- - **Consistency:** The same commands every time, reducing human error (e.g. forgetting migrations or cache clears). - **Speed:** Deploy in seconds instead of manually copying files and running commands. - **Safety:** Run tests or lint checks before code goes live, and restart services afterward. The Deploy Command ------------------ Use the CLI: .. code-block:: bash # Deploy to the default environment (as defined in shoedeploy.php) php lace deploy # Deploy to “production” explicitly php lace deploy production If you omit the environment name, LacePHP uses the **default** from your deploy config. Configuring Your Deployments ----------------------------- Edit or Create **shoedeploy.php** file in your project root: .. code-block:: php 'staging', // define each environment 'environments' => [ 'staging' => [ 'host' => 'staging.example.com', 'user' => 'root', 'path' => '/var/www/myapp', 'branch' => 'main', ], 'production' => [ 'host' => 'prod.example.com', 'user' => 'deploy', 'path' => '/var/www/myapp', 'branch' => 'main', ], ], // optional hooks you can customise 'hooks' => [ 'beforeDeploy' => function() { echo "🔎 Running local tests…\n"; passthru('php vendor/bin/phpunit', $code); if ($code !== 0) { throw new \RuntimeException("Tests failed, aborting deploy."); } }, 'afterDeploy' => function() { echo "⚙️ Restarting queue workers…\n"; passthru( "ssh {$this->user}@{$this->host} ". "'cd {$this->path}/current && php lace queue:restart'" ); }, ], ]; Key config entries: - **default** The environment name used when you run `php lace deploy` without args. - **environments** Map each name to `host`, `user`, `path` and Git `branch`. - **hooks** PHP callables for **beforeDeploy** and **afterDeploy** phases. Under the Hood: `ShoeDeploy::run()` ------------------------------------ 1. **Load** `shoedeploy.php` and select the environment. 2. **Echo** the target (e.g. `Deploying to [staging] root@staging.example.com:/var/www/myapp`). 3. **beforeDeploy hook** (if defined): run tests, linters, etc. 4. **SSH commands** in order: - Create a timestamped `releases/` directory - `git clone --branch {branch}` into that release folder - Update the `current` symlink to point at the new release - `composer install --no-dev --optimize-autoloader` inside `current` 5. **afterDeploy hook** (if defined): restart queues, clear cache, reload services. 6. **Success message** on completion. Basic Deployment Flow ---------------------- 1. Run `php lace deploy [env]`. 2. LacePHP reads your config and hooks. 3. Hooks run locally (tests, style checks). 4. Remote SSH steps update code, install dependencies. 5. Hooks run remotely (service restarts). 6. You see “Deployment to [env] succeeded!” Advanced Hooks Example ---------------------- **Before deploy** run both PHPCS and PHPUnit: .. code-block:: php 'hooks' => [ 'beforeDeploy' => function() { echo "🔎 Running code style and tests…\n"; passthru('vendor/bin/phpcs src', $c1); passthru('vendor/bin/phpunit', $c2); if ($c1 || $c2) { throw new \RuntimeException("Quality checks failed."); } }, ], **After deploy** clear cache and reload PHP-FPM: .. code-block:: php 'hooks' => [ 'afterDeploy' => function() { echo "Clearing cache…\n"; passthru( "ssh {$this->user}@{$this->host} ". "'cd {$this->path}/current && php lace cache:clear'" ); echo "Reloading PHP-FPM…\n"; passthru( "ssh {$this->user}@{$this->host} ". "'sudo systemctl reload php8.1-fpm'" ); }, ], Best Practices -------------- - **Test locally first**: Fail early by running your full test suite before remote changes. - **Branch strategy**: Deploy feature branches to staging, then merge for production. - **Keep hooks lean**: Offload heavy tasks to background jobs where possible. - **Secure SSH**: Use key-based authentication and restrict the deploy user’s permissions. .. warning:: - Deployment scripts run commands with your SSH user’s privileges—ensure you do not accidentally delete or expose sensitive data. - Hooks that fail will abort the deploy—handle exceptions and cleanup if partial changes occur. - Always monitor logs on the remote server after deploying to catch unexpected errors.