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

Vessel Laravel Package

shipping-docker/vessel

Vessel provides a lightweight, Docker-based local development environment for Laravel applications. It replaces Homestead/Vagrant with simple containers for PHP, MySQL, Redis, and more, making setup fast and reproducible across teams.

View on GitHub
Deep Wiki
Context7

Getting Started

Vessel is a Docker-based local development environment for Laravel — it ships a docker-compose.yml, per-service Dockerfiles, and a vessel CLI wrapper. You are not adding a runtime dependency to your app; you are adding a reproducible dev stack.

Minimal steps:

composer require shipping-docker/vessel --dev
php vendor/bin/vessel install   # publishes docker-compose.yml, docker/, .env.docker bits
./vessel up                     # or: docker-compose up -d

Then browse http://localhost. The generated docker-compose.yml exposes the app on :80, MySQL on :3306, and Redis on :6379.

Where to look first:

  1. docker-compose.yml at the repo root — the source of truth for services, ports, and volumes.
  2. docker/ — one directory per service (app, mysql, redis, etc.). The app Dockerfile is where PHP version, extensions, and Composer live.
  3. The vessel script — a thin wrapper; read it once so you know exactly which docker-compose exec each command maps to.
  4. .env — DB_HOST=mysql, REDIS_HOST=redis, DB_PORT=3306 (the container port, not the host-mapped one).

First real use case: get vessel artisan migrate and vessel composer install working, then point your IDE/DB client at 127.0.0.1:3306. That's the whole onboarding loop.

Upgrading to 6.0.0 specifically: after composer update, re-run the vendor install/upgrade step from the Vessel docs, then rebuild the app image — step 4 ("Rebuild Containers") of the upgrade guide — before vessel up. Skipping the rebuild leaves you on the old Ubuntu base and produces confusing "file exists / package not found" errors.

Implementation Patterns

Daily command wrapping. Treat vessel as the only entry point so nobody on the team shells into containers by hand:

vessel artisan make:model Invoice -m
vessel composer require laravel/horizon
vessel npm run dev
vessel mysql          # drops you into the MySQL client as the app user
vessel bash           # ad-hoc shell in the app container
vessel logs -f app

Alias it in your shell (alias v=vessel) — it removes the constant "do I need docker-compose exec app or docker-compose run?" friction.

Override, don't fork. Put project-specific tweaks in docker-compose.override.yml (Compose merges it automatically) rather than editing docker-compose.yml. Typical overrides: extra port mappings, a Mailhog/Mailpit service, mounting ~/.composer for cache reuse, or a xdebug env toggle. This keeps the published files upgradable across Vessel majors — which matters a lot at 6.0.0, where re-publishing would otherwise clobber your edits.

Extend the app image instead of editing it. If you need an extension, a Node version bump, or a custom entrypoint, add a small docker/app/Dockerfile layer or a build-arg toggled from .env. Vessel's app Dockerfile is deliberately plain Ubuntu + PHP; your additions survive base-image bumps better when they're additive.

Multi-service workflows. Queue workers and schedulers are the usual second/third container. Either add them as compose services sharing the same image and volume, or run them on demand (vessel artisan queue:work). For Horizon/Telescope, keep the worker service's command in docker-compose.override.yml so local and CI diverge cleanly.

CI parity. Because the stack is plain Compose, CI can reuse the same docker-compose.yml with docker-compose build app and run tests via docker-compose run --rm app vendor/bin/phpunit. Pin the base image tag and the Vessel composer constraint so a composer update on a laptop doesn't silently change the CI PHP version.

Swagger/static content. 6.0.0 lets PHP (via the built-in server) serve static content without an HTTP 303 redirect. If you serve generated API docs (L5-Swagger, api-docs.json, Swagger UI assets) from public/, verify they're still reachable through the app container after upgrading — that 303 was previously masking asset-resolution issues for some setups.

Predis handling. 6.0.0 stops installing Predis during init. If your app or a package relies on the predis client rather than the phpredis extension, add it explicitly (vessel composer require predis/predis) or switch REDIS_CLIENT to phpredis and ensure the extension is built into your app image. Decide this deliberately per project — it's now a project concern, not a Vessel default.

Gotchas and Tips

  • Rebuild after upgrading to 6.0.0. docker-compose build --no-cache app && vessel up. Layer caching is the #1 cause of "I upgraded but nothing changed." Ubuntu 20.04 brings newer PHP packages, so expect extension names/versions to shift; pin php versions in the Dockerfile if you need determinism.
  • DB_HOST=mysql, never 127.0.0.1. Inside the network, localhost is the app container. This is the most common first-run failure, and it surfaces as a SQLSTATE[HY000] [2002] connection refused.
  • Port collisions. 3306, 80, 6379 clash with a local MySQL/nginx/Redis or with a second Vessel project. Override the host side in docker-compose.override.yml ("3307:3306"), leaving the container port alone.
  • Permissions on Linux. Bind-mounted storage/ and bootstrap/cache/ often end up root-owned after container writes. Set UID/GID build args or run vessel bash as the matching user; otherwise artisan mysteriously fails to write logs.
  • macOS file sync. Large vendor/ on a bind mount is slow. Prefer named volumes for vendor//node_modules/ or enable the Docker file-sharing tuning; don't conclude Vessel is slow before checking this.
  • .env drift between host and container. Vessel's install writes container-appropriate values; if you later copy production .env down, you'll re-break DB/Redis hosts. Keep a .env.docker or document the three variables that must differ.
  • vessel vs docker-compose mismatch. If a teammate runs docker-compose up with an older Vessel, Compose file version differences bite. Pin the package version in composer.json (e.g. "shipping-docker/vessel": "^6.0") and commit the lockfile.
  • Don't commit generated artifacts blindly. Some installs create container-specific paths or .env copies — review git status after vessel install and after upgrading, and keep docker/ diffs small and intentional so the next major bump is a merge, not a rewrite.
  • GPG/key import failures during build. 6.0.0 disables IPv6 when importing GPG keys; if you're on an unusual network (VPN, forced IPv6), a failed build here is a network/environment issue, not a Dockerfile bug — retry off-VPN before editing the Dockerfile.
  • Xdebug is off by default. Enable it via an environment toggle in the override file and confirm the client port (9003 for Xdebug 3) — a silent, always-off debugger wastes hours.
  • Debugging recipe: vessel ps → vessel logs -f <service> → vessel bash into app → docker-compose config to verify merged YAML. Most "Vessel is broken" reports resolve at step 4 (the override file isn't merging what you think it is).
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings