Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Fleet Laravel Package

aschmelyun/fleet

Fleet is a lightweight Laravel package for deploying applications to your own servers with Docker. It offers simple Artisan commands to provision a server, build and ship containers, and manage deployments without complex infrastructure tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. composer require <vendor>/<package> — Laravel's package discovery registers the service provider automatically; no manual config/app.php edit needed on Laravel 9+.
  2. Publish config if the package ships one: php artisan vendor:publish --tag=<package>-config. Check config/<package>.php for paths, binary locations, and timeouts.
  3. Look first at composer.json constraints. v1.1.1's only change is a bump of symfony/yaml and symfony/process (fix for #22). Confirm your app doesn't pin older majors:
    composer why symfony/yaml
    composer why symfony/process
    
    If another dependency (test tooling, deploy scripts, older Symfony components) requires <5.4, the bump will stall the update — resolve before upgrading.
  4. First use case: parse a YAML definition and act on it via a subprocess. Typical shape:
    $definition = Yaml::parseFile(base_path('deploy.yaml'));
    $process = new Process(['git', 'rev-parse', '--short', 'HEAD']);
    $process->mustRun();
    

Implementation Patterns

Wrap YAML parsing behind a typed DTO. YAML parses to nested arrays with no schema. Map it once into a value object or config repository and validate there, rather than passing raw arrays through the app. This keeps symfony/yaml an internal detail and makes future parser swaps painless.

Bind it in the container. Register a singleton that resolves the config path and cache the parsed result per request:

$this->app->singleton(DeploymentDefinition::class, fn () => DeploymentDefinition::fromYaml(
    Yaml::parseFile(config('deploy.manifest'))
));

Long-running processes belong in jobs, not controllers. The symfony/process side of this package will block the request worker. Dispatch a queued job, give it a timeout slightly below retry_after, and stream output to a log or broadcast channel.

Prefer array-form commands. new Process(['bin/console', 'cache:clear']) avoids shell quoting entirely; the string form re-introduces escaping bugs on paths with spaces.

Use the package's Artisan surface for day-to-day work and its underlying services for programmatic cases — that keeps you on the supported path and makes behaviour identical between CLI and scheduled runs.

Test with fakes, not real subprocesses. Assert on the command array and mock the runner; only integration-test against the real binary in a dedicated suite. Tests that shell out are the usual cause of flaky CI on this kind of package.

Gotchas and Tips

  • The v1.1.1 bump is low-risk but not zero-risk. It is a patch release with no API changes, so behaviour should be identical — but transitive Symfony minors can shift parser edge cases. Run your YAML fixtures through Yaml::parse() after upgrading and diff the output before shipping.
  • symfony/yaml is not yaml_parse(). The PECL extension and Symfony's parser diverge on booleans (yes/no/on), timestamps, and !!php/object. Always parse with the parser the package actually uses.
  • Flags matter. Yaml::PARSE_DATETIME, PARSE_CONSTANT, and PARSE_CUSTOM_TAGS are off by default; values that look like dates silently become strings. Decide explicitly and document it.
  • Anchors and merges are supported; arbitrary tags are not. A manifest relying on custom !include tags throws ParseException — catch it and surface the file plus line number, or the error is opaque in production.
  • Never eval or unserialize parsed YAML. YAML from an untrusted source is an object-injection vector; keep manifests in the repo, not in user uploads.
  • Process exit codes are your signal, not output. Check $process->getExitCode() / use mustRun(). Some tools write errors to stdout, so grepping output is unreliable.
  • Always set a timeout. setTimeout(60) plus setIdleTimeout(15); the default is 60s and a hung child can pin a queue worker indefinitely.
  • Debugging failures: $process->getErrorOutput() and $process->getExitCodeText() are more useful than the exception message. Log both, plus the command array, on failure.
  • Environment leakage: Process inherits the parent env by default. Pass an explicit env array for anything touching credentials, and remember setWorkingDirectory() — relative paths in the child resolve against it, not your app root.
  • Cache parsed YAML in production. Parsing on every request is unnecessary I/O; key the cache on file mtime and clear it in your deploy step.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
adachsoft/php-code-style