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

Porto Laravel Package

nunomaduro/porto

Porto is a Laravel/PHP package by Nuno Maduro that simplifies Docker-based development environments, helping you containerize applications and manage services with a clean, streamlined workflow for local and production use. It aims to make containerized PHP setups easy to configure and run.

View on GitHub
Deep Wiki
Context7

Getting Started

Verify the package identity before you install. The manifest name is nunomaduro/porto and the repository is laravel/vet, which is a mismatch. Run composer show nunomaduro/porto after the install and confirm the reported source URL is https://github.com/laravel/vet. If it is not, add the repository explicitly in composer.json and pin the constraint:

"repositories": [
    { "type": "vcs", "url": "https://github.com/laravel/vet" }
]

Install it as a development dependency, because a dependency audit is a build-and-review tool and not a runtime library:

composer require --dev nunomaduro/porto:^0.2.1

Pin at least 0.2.1. That release fixes a config-parsing bug, and the fix is directly in the path of the first thing you will want to configure — see below.

Read README.md first, then go to the console command class in src/. This project keeps its contributor instructions in AGENTS.md and .hod/PROJECT.md, so the intent of a flag or a check is easier to find in the command class than in prose. Run the binary with --help from vendor/bin/ to get the exact flag names for the version you installed, and do not trust a flag name from a blog post.

Configuration lives in a vet.json file at the project root. As of 0.2.1 that file may contain nothing but the minimum release age setting, so a one-line config is a valid config:

{
    "minimumReleaseAge": 604800
}

Start there. The minimum release age check is the cheapest thing this tool does for you: it flags dependencies whose release is younger than the threshold, which is exactly the window in which a compromised or typosquatted version gets pulled before anyone notices. Pick a threshold in seconds that matches how fast you want composer update to be able to move, then run the audit against your own composer.lock on a branch where you have just run composer update, read the report, and pick one finding to act on. This gives you a real result in under a minute and tells you how noisy the tool is for your dependency set before you put it in CI.

Make it a single command so people actually run it. Add a composer script:

"scripts": {
    "audit": "@php vendor/bin/vet"
}

Implementation Patterns

Put every setting in vet.json, not in the CI YAML. The config file is the reviewable artifact: thresholds, exclusions, and check selection all belong in a committed file so that a change to the audit's strictness shows up in the diff of a pull request. Before 0.2.1 you could not ship a config that only set the release age, so older installs forced you to duplicate defaults. If you find yourself passing the same flag on the command line in two places, move it into the file.

Gate composer update pull requests, not every pull request. The set of installed packages changes only when the lock file changes. Run the audit as a path-filtered job on composer.lock and composer.json. A job on every push trains people to ignore a red check that is unrelated to their change.

Run against the lock file, not the manifest. An audit of composer.json reports what you could install. An audit of composer.lock reports what you deploy. Keep the two consistent by auditing in the same job that installs with composer install --no-interaction.

Separate the human report from the exit code. Print the full report to the job log for a human, and keep the exit status for the gate. When a finding is accepted as a risk, suppress it in vet.json, not in the CI YAML — that keeps the suppression list reviewable in the repository and applied identically on a laptop. If the version you installed turns out not to have a suppression mechanism for a given finding, add an ignore entry to the config where one exists, and only fall back to a wrapper script for what the config cannot express. Wrap the invocation in a small script that filters known identifiers and exits non-zero on anything new only as a last resort.

Make the audit step non-blocking on day one. Add the job with continue-on-error: true or without a required-check setting. Collect the findings for a week, clean up the accepted noise, then make the check required. A blocking audit introduced on a codebase with a long backlog gets disabled within a sprint. The minimum release age check is the exception: it is usually quiet on a codebase that already pins versions, so it can be required earlier than the advisory checks.

Pair it with a scheduled run. A lock file is stale the moment it is committed. Add a weekly schedule trigger that runs the audit against the current lock file, so a new advisory against an unchanged dependency still surfaces. Route the failure to the same place your other dependency alerts go.

Run it in the PHP version matrix you support. Advisory resolution and package metadata can differ per platform, so mirror the PHP versions from your test matrix rather than auditing on one interpreter.

Use it locally as a pre-push check, not a pre-commit hook. The audit takes long enough that a commit hook becomes an obstacle. A composer audit script people run before opening a pull request, plus the CI gate, covers both ends with no added friction.

Treat the report as a triage input, not a verdict. For each finding decide: upgrade now, accept with a written reason, or remove the dependency. The third option is the one people forget.

Gotchas and Tips

The name and the repository disagree. nunomaduro/porto does not describe an audit tool, and the repository URL is laravel/vet. The package has no dependents, so no other project has validated the install path for you. Confirm the source URL on every clean install, and use a committed composer.lock in CI so a moving tag cannot change what you audit.

vet.json with only a release age setting was broken before 0.2.1. Older versions rejected a config file that omitted everything else, which meant the smallest possible config did not work and you had to restate defaults to use the setting. Require ^0.2.1 or newer, and if you inherit a project pinned lower, check whether its vet.json is silently falling back to defaults.

Prove the config file is actually read. A config bug in this area has already shipped once, and a schema that ignores an unknown key looks exactly like a config that worked. Set minimumReleaseAge to an absurdly high value, run the audit, and confirm the report changes. Do this on every upgrade of the package — not just once.

The release metadata is dated in the future. The last release is listed as 2026-09-27. Do not build automation that compares release dates, and do not assume a semantic-version promise. Pin an exact version and upgrade deliberately.

Documentation is written for agents, not for you. AGENTS.md and .hod/PROJECT.md hold the project's own construction rules: no comments in source, Simplified Technical English, one instruction per sentence. Read AGENTS.md to understand why the code looks the way it does, not to learn the tool's flags. For usage, read the command class in src/. If the README is thin, that is the reason — the 0.2.1 fix is documented nowhere except the release note.

A stale builds/vet binary is expected. The project states that a builds/vet older than the source is normal. If you build from source and your change appears to have no effect, rebuild before you debug. A stale binary looks exactly like a logic bug — including a config fix that appears not to have landed.

Extending it means following the project's rules. If you fork or patch, the constraints are concrete: put a test double in tests/Fixtures/, call the Laravel helper before writing a routine by hand, put each value and each command inside square brackets in a message, and write no nullable type or default value on any parameter of a constructor, method, function or closure. A patch that breaks one of these will not merge. A rule file in .hod/rules/ needs the user's agreement before you add it, and the rule list in section 6 of AGENTS.md must be updated in the same change.

Debug by invoking the binary directly. Running through composer run audit merges composer's own output with the tool's. Call vendor/bin/vet from the shell when you need to read the report or check the exit code, then move back to the composer script for the workflow.

Check where advisory data comes from before you trust a clean result. If the run depends on a network source and the fetch fails silently, a clean report means nothing. Force a failure once — run it with no network — and confirm the tool reports an error rather than a pass.

Keep it out of production. A --dev install means the audit code never enters the deployed autoloader. Do not add it to require, even when a deployment pipeline wants to run it, because that pipeline can install dev dependencies in its own job.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core