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:

# 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:

<?php
return [
    // default target if none specified on the command line
    'default' => '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:

'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:

'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.