foxws / laravel-podman
Podman Quadlet support to your Laravel application
Fund package maintenance!
Requires
- php: ^8.4
- composer-runtime-api: ^2.0
- illuminate/console: ^11.0|^12.0|^13.0
- illuminate/contracts: ^11.0||^12.0||^13.0
- illuminate/filesystem: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- spatie/laravel-package-tools: ^1.16
- symfony/console: ^6.0|^7.0|^8.0
Requires (Dev)
- aws/aws-sdk-php: ^3.322
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^11.0.0||^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
Suggests
- aws/aws-sdk-php: Required to use the "podman:s3-setup" command (^3.322).
Provides
None
Conflicts
None
Replaces
None
- dev-main
- 5.3.1
- 5.3.0
- 5.2.0
- 5.1.1
- 5.1.0
- 5.0.1
- 5.0.0
- 4.0.4
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.0.1
- 3.0.0
- 2.1.11
- 2.1.10
- 2.1.9
- 2.1.8
- 2.1.7
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.0
- 1.9.0
- 1.8.0
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.0
- 1.5.0
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.0
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.0.2
- 0.0.1
- dev-dev-dependency-for-development-only
- dev-keep-app-cache-on-dev-start
- dev-phpstan-level-8
- dev-add-homepage-group
- dev-devcontainer-optional-mounts
This package is auto-updated.
Last update: 2026-10-02 18:47:30 UTC
README
Run your Laravel app and its services as Podman Quadlet containers, managed by systemd on your own Linux machine or server.
The package renders ready-to-use presets from your app's config: the app on Octane and FrankenPHP, a database, cache, queue worker, search, object storage, a mail catcher and a Caddy proxy. You install them with one command each. There's no all-in-one runtime and no lock-in: the output is plain Quadlet files you can read, change or replace.
Upgrading from an earlier major version? See UPGRADING.md.
Features
Presets for every stage
development: your working copy mounted live, Octane with file watching, Xdebug (off until you turn it on), and an optional Vite dev server.production: a FrankenPHP and Octane image with your code baked in, Inertia SSR, and the queue worker and scheduler running independently of the app.devcontainer: a Dev Containers image for VS Code and JetBrains, with an optional AI variant (Claude Code, Codex, Laravel LSP).proxy: Caddy in front of everything, with HTTPS (local certificates in development, Let's Encrypt in production) and subdomains for Vite, Reverb, S3 and Mailpit.
Services included, one per category
| Category | Services (default first) |
|---|---|
| Database | PostgreSQL, MariaDB, MySQL, MongoDB |
| Cache | Valkey, Redis, Memcached |
| Queue worker | queue:work, Horizon |
| Search | Typesense, Meilisearch |
| Object storage | RustFS (S3-compatible) |
| Mail catcher | Mailpit |
| Also | Scheduler, Reverb, Inertia SSR |
Scale to zero
- The app starts on its first request and stops after 10 minutes without traffic (on-demand services). Change the timeout with
PODMAN_ONDEMAND_IDLE_TIMEOUT, e.g.5min,30minor2h. - The database, cache and other services sleep too, once no jobs are left.
- Works behind the bundled proxy or your own, such as a NAS or Nginx on another machine.
- Set
PODMAN_ONDEMAND_ENABLED=falseto keep everything running all the time.
Native to your system
- Plain systemd units that work rootless or system-wide. Services restart on failure. The proxy, the app's socket and the production workers start at boot.
- Database, cache and proxy images are pinned to a major version, and every container is set up for
podman auto-update. - Production secrets, like your
.env, are stored as Podman secrets instead of files. - SELinux-aware volume mounts, which you can turn off on hosts without SELinux.
Yours to customize
- Publish just the preset you want to change. The rest keep following package updates.
- Swap services, add your own, or set memory limits with plain Quadlet files and
{{placeholders}}. - Add your own placeholders from
config/podman.php.
Tooling
lpod, a small CLI for installing services and running Artisan, Composer, Node and tests inside your containers.lpodalso turns Xdebug on and off, and checks your host withlpod doctor.podman:s3-setupcreates your S3 buckets and applies a CORS policy.- Render presets on a host without PHP with
lpod setup. - An example CI workflow builds and pushes a multi-arch production image.
- Laravel Boost skills, so AI agents know how to run commands in, customize and upgrade your setup.
Requirements
- Linux with systemd (rootless or system-wide). macOS, Windows and WSL aren't supported.
- Podman with Quadlet support (
podman quadlet --helpshould work).
Installation
composer require foxws/laravel-podman
php artisan vendor:publish --tag="podman-config"
If you run production in these containers, install it as a regular dependency, not with --dev: the idle check runs php artisan podman:idle inside them, and production images are built without dev dependencies. If you only use it for development and deploy elsewhere, --dev is preferred. Where it is installed but shouldn't touch services, set PODMAN_ENABLED=false: podman:generate, podman:setup, podman:publish and podman:s3-setup then refuse to run. See Customizing for every config key.
Quick start
-
Render the default presets (
development,ondemandandproxy):php artisan podman:setup
-
Install
lpodonce per host. It's a single bash script and doesn't need PHP. Upgrade it later withlpod self-update:curl -fsSL https://github.com/foxws/lpod/releases/latest/download/install.sh | bash -
Install the services. Replace
my-appwith your app's name (APP_NAME, kebab-cased):lpod install development/app.quadlets --replace lpod install development/pgsql.quadlets --replace lpod install development/valkey.quadlets --replace lpod install ondemand/my-app-ondemand.socket --replace lpod install proxy/proxy.quadlets --replace lpod idle enable my-app -
Open your app. The first request starts it:
lpod my-app open
-
Trust the proxy's local certificate once. See Proxy.
For frontend work, run pnpm install and add the Vite dev server:
lpod install development/vite.quadlets --replace lpod my-app-vite up
For production, also set the secrets it expects, such as your .env and the database password, with lpod my-app secrets and lpod my-app-pgsql secrets.
Commands
| Command | Description |
|---|---|
podman:setup |
Render the default presets |
podman:publish PRESET |
Copy a preset into your project to customize it |
podman:generate PRESET |
Render a single preset |
podman:s3-setup |
Create S3 buckets and apply a CORS policy (needs aws/aws-sdk-php) |
podman:idle |
Succeed when the app has no work in progress, for stopping idle queue workers |
Everything else, like installing, starting, removing and setting secrets, is done with lpod:
lpod my-app artisan migrate lpod my-app composer require laravel/horizon lpod my-app pest lpod my-app shell
Warning:
lpod removeandlpod uninstalldelete the service's Podman volumes, including databases and uploads. There's no undo. See Backing up volumes.
Documentation
The full documentation is at foxws.nl/laravel-podman:
- Getting started: Commands,
lpodCLI - Configuration: Customizing, Devcontainer, Proxy, S3 Buckets, On-demand services
- Advanced: Setting up without PHP, CI: Building a Container Image
- Reference: Comparison with Sail, Herd and others
Testing
composer test
Links
- CHANGELOG
- Upgrade guide
- Security policy
- foxws/lpod, the CLI this package pairs with
- Podman Quadlet reference
Credits
- francoism90
- All Contributors
- Spatie: the idle checks follow the design of spatie/laravel-health's checks
AI, specifically Claude, was used to help build this package. All AI-assisted output is reviewed by me, and I retain final say over everything that is implemented and released.
License
MIT. See License File.