PHPackages                             matheusmarnt/quick-deploy - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [DevOps &amp; Deployment](/categories/devops)
4. /
5. matheusmarnt/quick-deploy

ActiveLibrary[DevOps &amp; Deployment](/categories/devops)

matheusmarnt/quick-deploy
=========================

A strategy-based deployment automation package for Laravel applications with Docker support

v0.2.0(2mo ago)02MITPHPPHP ^8.2CI passing

Since Mar 2Pushed 2mo agoCompare

[ Source](https://github.com/matheusmarnt/quick-deploy)[ Packagist](https://packagist.org/packages/matheusmarnt/quick-deploy)[ Docs](https://github.com/matheusmarnt/quick-deploy)[ RSS](/packages/matheusmarnt-quick-deploy/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (5)Versions (5)Used By (0)

    ![QuickDeploy Logo](images/logo-quick-deploy.png)

A strategy-based deployment automation package for Laravel applications with Docker support.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Docker &amp; Docker Compose
- Composer

Installation
------------

[](#installation)

```
composer require matheusmarnt/quick-deploy
```

The `QuickDeployServiceProvider` is auto-discovered by Laravel.

### Publishing Deployment Files

[](#publishing-deployment-files)

```
./vendor/bin/sail artisan quick-deploy:install
```

This copies Makefile, scripts, Docker configs, compose files and `.env` templates to your project root.

FlagDescription`--force`Overwrite existing files without asking`--scripts`Install only the Makefile and `scripts/` directory`--docker`Install only compose files and `docker/` configs`--env-files`Install only `.env` templates### Quick Start

[](#quick-start)

```
php artisan quick-deploy:install
make help       # List all commands
make deploy     # Interactive deployment menu
make deploy-dev # Deploy for development
```

Architecture
------------

[](#architecture)

QuickDeploy uses the **Strategy Pattern** — the `Deployer` delegates to a `DeploymentStrategy` that encapsulates the full pipeline for each environment.

```
Deployer ──> DeploymentStrategy (interface)
                    ▲
         ┌──────────┼──────────┐
         │                     │
  DevelopmentDeployment  ProductionDeployment
  (Sail + MySQL)         (Compose + MySQL + Redis + Nginx)

```

The service provider auto-detects the environment and wires the correct strategy:

- **Development** — uses `SailOrchestrator`, health checks MySQL only, timeout 30s
- **Production** — uses `DockerComposeOrchestrator`, checks MySQL + Redis, timeout 60s

PHP API Usage
-------------

[](#php-api-usage)

### Basic Deploy

[](#basic-deploy)

```
use Matheusmarnt\QuickDeploy\Config\DeploymentContext;
use Matheusmarnt\QuickDeploy\Deployer;

$deployer = app(Deployer::class);

$context = new DeploymentContext(
    projectName: 'My App',
    projectSlug: 'my-app',
    workingDirectory: base_path(),
);

$result = $deployer->deploy($context);

if ($result->success) {
    echo "Deployed in {$result->totalDuration}s";
} else {
    echo "Failed: {$result->message}";
    // Rollback is automatic on failure
}
```

### DeploymentContext — All Options

[](#deploymentcontext--all-options)

`DeploymentContext` is an immutable value object with all deploy configuration:

```
$context = new DeploymentContext(
    projectName: 'My App',              // Human-readable name
    projectSlug: 'my-app',              // URL-safe identifier (used in container names)
    workingDirectory: base_path(),       // Absolute path to project root
    environment: 'production',           // 'development' or 'production'
    composeFile: 'compose.production.yaml', // Docker Compose file name
    envTemplate: '.env.production.example', // Source template for .env
    ports: [                             // Service port overrides
        'app' => 8080,
        'mysql' => 3307,
    ],
    envVariables: [                      // Variables injected into .env
        'APP_URL' => 'https://myapp.com',
        'DB_PASSWORD' => 'secret',
    ],
    options: [                           // Strategy-specific options
        'healthCheckTimeout' => 120,     // Production: seconds to wait for services
    ],
);
```

Use `with()` to create a modified copy:

```
$staging = $context->with([
    'environment' => 'production',
    'composeFile' => 'compose.staging.yaml',
]);
```

### Validating Before Deploy

[](#validating-before-deploy)

```
$errors = $deployer->validate($context);

if (! empty($errors)) {
    foreach ($errors as $error) {
        echo "- {$error}\n";
    }
    return;
}

$deployer->deploy($context);
```

Validation checks:

- Working directory exists
- Template file (`.env.example`) exists
- **Production only**: environment must be `'production'`

### Inspecting Deploy Results

[](#inspecting-deploy-results)

`DeploymentResult` contains the outcome of each pipeline step:

```
$result = $deployer->deploy($context);

// Overall result
$result->success;        // bool
$result->strategy;       // 'development' or 'production'
$result->totalDuration;  // float (seconds)
$result->message;        // Error reason on failure

// Individual steps
foreach ($result->steps as $step) {
    echo "{$step['step']}: " . ($step['success'] ? 'OK' : $step['message']);
    echo " ({$step['duration']}s)\n";
}

// Only failed steps
$result->failedSteps();
```

### Switching Strategies

[](#switching-strategies)

```
$deployer = app(Deployer::class); // Starts with auto-detected strategy

// Switch to production
$deployer->useStrategy('production');

// Or register a custom strategy
$deployer->register(new StagingDeployment(/* ... */));
$deployer->useStrategy('staging');

// Check available strategies
$deployer->availableStrategies(); // ['development', 'production', 'staging']
```

### Explicit Rollback

[](#explicit-rollback)

Rollback is automatic on deploy failure, but you can trigger it manually:

```
$deployer->rollback($context);
// Stops containers + restores .env from .env.backup
```

### Health Checks

[](#health-checks)

Health checkers are used internally during deploy, but can also be used directly:

```
use Matheusmarnt\QuickDeploy\Contracts\HealthChecker;

$checker = app(HealthChecker::class);
$result = $checker->check(base_path(), timeoutSeconds: 30);

if ($result->healthy) {
    echo "{$result->service} is up ({$result->responseTimeMs}ms, {$result->attemptsUsed} attempts)";
} else {
    echo "{$result->service} failed: {$result->message}";
}
```

### Environment Configuration

[](#environment-configuration)

Read, write and validate `.env` files programmatically:

```
use Matheusmarnt\QuickDeploy\Contracts\EnvironmentConfigurator;

$env = app(EnvironmentConfigurator::class);

// Create .env from template with variable overrides
$env->configure(
    templatePath: base_path('.env.example'),
    targetPath: base_path('.env'),
    variables: ['APP_URL' => 'https://myapp.com'],
);

// Read/write individual values
$env->set(base_path('.env'), 'APP_DEBUG', 'false');
$value = $env->get(base_path('.env'), 'APP_URL'); // 'https://myapp.com'

// Check required keys exist and have values
$missing = $env->validateRequired(base_path('.env'), [
    'APP_KEY', 'APP_URL', 'DB_PASSWORD',
]);
// Returns: ['APP_KEY'] if APP_KEY is empty
```

### Port Management

[](#port-management)

Check port availability before deployment:

```
use Matheusmarnt\QuickDeploy\Environment\PortManager;
use Matheusmarnt\QuickDeploy\Support\ProcessRunner;

$portManager = new PortManager(app(ProcessRunner::class));

// Check a port
$portManager->isPortInUse(3306); // true/false

// Find conflicts in a set of ports
$conflicts = $portManager->findConflicts([
    'app' => 80,
    'mysql' => 3306,
]);
// Returns: ['mysql' => 3306] if 3306 is in use

// Find an available port
$port = $portManager->suggestAlternative(8080); // 8081, 8082, etc.
```

### Container Orchestration

[](#container-orchestration)

Execute Docker commands through the orchestrator abstraction:

```
use Matheusmarnt\QuickDeploy\Contracts\ContainerOrchestrator;

$docker = app(ContainerOrchestrator::class);
$dir = base_path();
$compose = 'compose.yaml';

$docker->build($dir, $compose);    // docker compose build --no-cache
$docker->up($dir, $compose);       // docker compose up -d
$docker->down($dir, $compose);     // docker compose down
$docker->restart($dir, $compose);  // docker compose restart

// Run a command inside a container
$output = $docker->run($dir, $compose, 'app', [
    'php', 'artisan', 'migrate', '--force',
]);
```

The orchestrator auto-selects `SailOrchestrator` (dev) or `DockerComposeOrchestrator` (prod) based on the presence of `vendor/bin/sail`.

### Creating a Custom Strategy

[](#creating-a-custom-strategy)

Implement `DeploymentStrategy` for custom environments:

```
use Matheusmarnt\QuickDeploy\Contracts\DeploymentStrategy;
use Matheusmarnt\QuickDeploy\Config\DeploymentContext;
use Matheusmarnt\QuickDeploy\Result\DeploymentResult;

final class StagingDeployment implements DeploymentStrategy
{
    public function __construct(
        private readonly ContainerOrchestrator $orchestrator,
        private readonly EnvironmentConfigurator $envConfigurator,
        private readonly HealthChecker $healthChecker,
    ) {}

    public function name(): string
    {
        return 'staging';
    }

    public function validate(DeploymentContext $context): array
    {
        $errors = [];

        if (! is_dir($context->workingDirectory)) {
            $errors[] = 'Working directory does not exist.';
        }

        return $errors;
    }

    public function deploy(DeploymentContext $context): DeploymentResult
    {
        $start = microtime(true);
        $steps = [];

        // 1. Setup environment
        $this->envConfigurator->configure(
            $context->templateFilePath(),
            $context->envFilePath(),
            $context->envVariables,
        );
        $steps[] = ['step' => 'Environment Setup', 'success' => true, 'message' => '', 'duration' => 0.0];

        // 2. Build and start
        $this->orchestrator->build($context->workingDirectory, $context->composeFile);
        $this->orchestrator->up($context->workingDirectory, $context->composeFile);

        // 3. Health check
        $health = $this->healthChecker->check($context->workingDirectory);

        if (! $health->healthy) {
            return DeploymentResult::failed('staging', $steps, microtime(true) - $start, $health->message);
        }

        return DeploymentResult::succeeded('staging', $steps, microtime(true) - $start);
    }

    public function rollback(DeploymentContext $context): void
    {
        $this->orchestrator->down($context->workingDirectory, $context->composeFile);
    }
}
```

Register it:

```
$deployer = app(Deployer::class);
$deployer->register(new StagingDeployment(
    app(ContainerOrchestrator::class),
    app(EnvironmentConfigurator::class),
    app(HealthChecker::class),
));
$deployer->useStrategy('staging');
$deployer->deploy($context);
```

Deploy Pipeline
---------------

[](#deploy-pipeline)

### Development

[](#development)

StepAction1. EnvironmentCreates `.env` from template, backs up existing2. Build`sail build --no-cache`3. Start`sail up -d`4. HealthMySQL ping (30s timeout)5. Migrate`php artisan migrate --seed --force`6. Optimize`php artisan optimize:clear`### Production

[](#production)

StepAction1. EnvironmentCreates `.env`, forces `APP_ENV=production` and `APP_DEBUG=false`2. ValidateChecks required keys: `APP_KEY`, `APP_URL`, `DB_*`3. Stop`docker compose down` (clean slate)4. Build`docker compose build --no-cache`5. Start`docker compose up -d`6. HealthMySQL + Redis ping (60s timeout)7. Migrate`php artisan migrate --force` (no seed)8. Optimize`php artisan optimize` (cache all)On failure at any step, rollback runs automatically: stops containers and restores `.env` from backup.

Available Make Commands
-----------------------

[](#available-make-commands)

CommandDescription`make deploy`Interactive deployment menu`make deploy-dev`Development deployment`make deploy-prod`Production deployment`make up` / `make down`Start / stop containers`make logs`Follow container logs`make status` / `make health`Container status / health check`make restart` / `make clean`Restart / remove everything`make migrate`Run migrations`make migrate-fresh`Drop and re-run migrations`make migrate-seed`Migrations with seeding`make shell`App container shell`make mysql-shell` / `make redis-cli`Database shells`make composer` / `make npi` / `make nrb`Dependency management`make optimize` / `make backup` / `make pull`MaintenanceQuality Scripts
---------------

[](#quality-scripts)

```
composer test           # Run Pest tests
composer test:coverage  # Run tests with coverage
composer analyze        # Run PHPStan (level max)
composer format         # Fix code style with Pint
composer check          # Run all checks
```

Contributing
------------

[](#contributing)

1. Fork the repository.
2. Create a feature branch: `git checkout -b feature/my-feature`.
3. Write tests for your changes.
4. Run `composer check` to ensure quality.
5. Submit a pull request.

License
-------

[](#license)

MIT. See [LICENSE](LICENSE) for details.

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance85

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

77d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6405d6af1aecca19bec030f144d0c5a7abc129751c13ea40fb8fb2a9db2fd3f9?d=identicon)[matheusmarnt](/maintainers/matheusmarnt)

---

Top Contributors

[![matheusmarnt](https://avatars.githubusercontent.com/u/105521310?v=4)](https://github.com/matheusmarnt "matheusmarnt (15 commits)")

---

Tags

laravelautomationdevopsdockerdeployStrategy Pattern

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/matheusmarnt-quick-deploy/health.svg)

```
[![Health](https://phpackages.com/badges/matheusmarnt-quick-deploy/health.svg)](https://phpackages.com/packages/matheusmarnt-quick-deploy)
```

###  Alternatives

[aschmelyun/fleet

Run multiple Laravel Sail websites on your local environment

33269.5k](/packages/aschmelyun-fleet)[ideato/idephix

PHP automation and deploy tool.

6533.1k](/packages/ideato-idephix)[downtoworld/laravel-devops

Laravel Cloudflare-Tunnels Ready Production Docker-Compose

161.1k](/packages/downtoworld-laravel-devops)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
