foxws/laravel-podman

Podman Quadlet support to your Laravel application

Maintainers

Package info

github.com/foxws/laravel-podman

pkg:composer/foxws/laravel-podman

Transparency log

Fund package maintenance!

Foxws

Statistics

Installs: 99

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

1.0.3 2026-07-16 08:53 UTC

This package is auto-updated.

Last update: 2026-07-16 09:09:31 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Laravel Podman is a lightweight Laravel package that brings Podman Quadlet support to your app. It generates services from presets and installs them as systemd-managed containers.

It relies on your host Podman/systemd setup (instead of an all-in-one runtime), so it gives you a more advanced and flexible setup. You can swap bundled parts like the default Caddy proxy for your own setup (for example Nginx).

Features

  • Ready presets — Use built-in presets for common needs: frankenphp-octane, development, devcontainer, and proxy. You can also add your own. See Presets.
  • Generate first, install later — Artisan commands create Quadlet files from your app config. Then lpod installs and manages those services on the host.
  • Simple daily commands with lpod — Start and stop services, open a shell, run app commands, and manage installed units from one CLI.
  • Setup without host PHP (lpod-setup) — Render presets on machines that have Podman but not PHP installed.
  • Safe secret handling (lpod-secrets) — Store .env values and service passwords as Podman secrets instead of plain text files.

See the docs/ folder for more: Command Reference, Setting up without PHP on the host, Proxy, S3 Buckets, The lpod CLI, Customizing, Comparison.

Requirements

  • Linux with systemd (rootless or system-wide); macOS and Windows, including WSL, are not supported
  • A recent version of Podman with the quadlet CLI plugin (podman quadlet --help should work)

Installation

You can install the package via composer:

composer require foxws/laravel-podman

You can publish the config file with:

php artisan vendor:publish --tag="podman-config"

This is the contents of the published config file:

return [
    'enabled' => env('PODMAN_ENABLED', true),

    'presets' => env('PODMAN_DEFAULT_PRESETS', [
        // 'development',
        // 'devcontainer',
        'frankenphp-octane',
        'proxy',
    ]),

    's3_buckets' => env('PODMAN_S3_BUCKETS', [
        'local',
        'assets',
        'media',
        'conversions',
    ]),

    's3_cors_buckets' => env('PODMAN_S3_CORS_BUCKETS', [
        'conversions',
        'assets',
    ]),

    'quadlet_prefix' => env('PODMAN_QUADLET_PREFIX', env('APP_NAME', 'laravel')),

    'proxy_prefix' => env('PODMAN_PROXY_PREFIX', 'proxy'),

    'stubs_path' => env('PODMAN_STUBS_PATH', 'containers/stubs'),

    'working_path' => env('PODMAN_WORKING_PATH'),

    'quadlet_uid' => env('PODMAN_QUADLET_UID'),

    'quadlet_gid' => env('PODMAN_QUADLET_GID'),

    'publish_path' => env('PODMAN_PUBLISH_PATH', 'podman'),

    'selinux_volume_mapping' => env('PODMAN_SELINUX_VOLUME_MAPPING', true),
];

quadlet_prefix is used to namespace the services installed for your application (for example laravel-pgsql), and defaults to your APP_NAME. quadlet_uid/quadlet_gid default to the UID/GID of the user running the Artisan command. s3_buckets/s3_cors_buckets are used by podman:s3-setup — see S3 Buckets.

development is commented out by default — enable it (or pass --preset=development to podman:setup/podman:generate) if you want your working copy live-mounted into the container instead of baked into the image.

Presets

Preset Purpose
frankenphp-octane Production-style app image (code baked in) plus its full set of sibling services — database, cache, queue worker, WebSockets, scheduler, SSR, search, S3-compatible storage, mail catcher.
development The same services, but with your working copy live-mounted into the container instead of baked in, for local editing. Commented out by default — see the config above.
devcontainer An image for the VS Code/JetBrains Dev Containers workflow. Not Quadlet-managed — just a Containerfile and devcontainer.json, no quadlets/.
proxy Caddy reverse proxy terminating HTTPS in front of the other services. See Proxy.
s3 A cors.json policy applied by podman:s3-setup against your S3-compatible storage buckets. Not Quadlet-managed either — no quadlets//runtimes/, just the one file. See S3 Buckets.

Custom presets. A preset is a folder containing a quadlets/ directory of *.quadlets files and a runtimes/ directory of container build files (the devcontainer/s3 presets are exceptions — see the table above). stubs_path (default containers/stubs) is the lookup root for custom presets. For each preset name, the package uses stubs_path/{preset} if it exists; otherwise it falls back to the bundled vendor preset. Once a preset exists under stubs_path, that preset is fully overridden (no file-by-file merge). So you can publish one preset (php artisan podman:publish frankenphp-octane) without touching the others.

Quick Start

The fastest way to render an application's Quadlet units is podman:setup. It generates the default presets' .quadlets/runtime build files in one go, so you don't need to call podman:generate per preset:

php artisan podman:setup

Note: This step only renders files — it substitutes your app's config into the preset's templates and writes the result to the publish_path config key (podman by default, one subfolder per preset). It never touches the podman binary, so it works even without Podman installed (e.g. inside a disposable php container in CI). If you don't have PHP on the host at all, see Setting up without PHP on the host.

Generated files in publish_path (default podman/) are build artifacts. Do not commit them. Add the path to .gitignore (default: /podman), and remove/re-generate it any time after lpod install.

The presets it generates by default come from the presets config key (frankenphp-octane/proxy out of the box; development/devcontainer are opt-in — see Presets) — edit that, set PODMAN_DEFAULT_PRESETS, or override per run:

php artisan podman:setup --preset=frankenphp-octane

Installing is a separate step, handled by lpod on the host (this is the one step that actually needs the podman binary):

vendor/bin/lpod install frankenphp-octane/app.quadlets --replace
vendor/bin/lpod install frankenphp-octane/pgsql.quadlets --replace
vendor/bin/lpod install frankenphp-octane/valkey.quadlets --replace
vendor/bin/lpod install proxy/proxy.quadlets --replace
# ...and so on for every service you need.

Note: devcontainer and s3 aren't Quadlet-managed (see Presets), so there's nothing to lpod install for them — build the devcontainer image through your editor's Dev Containers extension, and run s3's CORS policy through podman:s3-setup instead.

Secrets a service needs (e.g. your application's .env file, database credentials) are prompted for and set once the service is installed, by unit name:

vendor/bin/lpod secrets app
vendor/bin/lpod secrets pgsql

Once installed, use lpod to start everything:

vendor/bin/lpod my-app up
vendor/bin/lpod my-app open   # Opens the application URL in your browser

The bundled proxy preset terminates HTTPS with a locally-trusted certificate — trust it once so your browser/OS stop flagging it, see Trusting the local certificate.

Setting up somewhere PHP isn't installed (a disposable container, CI)? Once lpod itself is on the host, vendor/bin/lpod setup (a shortcut for the lpod-setup binary — see The lpod utility) renders the default presets the same way, without needing PHP:

vendor/bin/lpod setup
vendor/bin/lpod setup --preset=frankenphp-octane

See Setting up without PHP on the host for the raw podman run ... equivalent (e.g. before lpod is available at all) and the details of what gets rendered where.

Usage

The package discovers preset folders (each containing a quadlets/ directory of *.quadlets files and a runtimes/ directory of container build files) on disk, and exposes them through Artisan commands that only ever render — never install. Every command that needs a preset name will prompt you to select one interactively when it's omitted. Full flag reference and examples: Command Reference.

Command Description
podman:setup Generate the default set of presets in one go (see Quick Start)
podman:publish PRESET Publish a preset (its quadlets and runtime files) for customization
podman:generate PRESET Render a single preset's quadlets and runtime files
podman:s3-setup Create S3 buckets and a CORS policy (requires aws/aws-sdk-php, see S3 Buckets)

Installing, listing, printing, removing, and setting secrets for the rendered services is lpod's job, not Artisan's — see below.

Warning: lpod remove/lpod uninstall delete the Podman volumes owned by the services they remove (databases, uploaded files, search indexes), with no undo. Back up first — see Backing up volumes.

The lpod utility

The package ships three Composer binaries that all run on the host — they talk to the real podman/systemctl binaries, unlike the Artisan podman:* commands, which only render templates and can run anywhere PHP is available:

  • vendor/bin/lpod — a thin wrapper around podman exec, podman quadlet, and systemctl for the Quadlet services rendered by Artisan, similar in spirit to Laravel Sail's sail script.
  • vendor/bin/lpod-setup — renders presets by running php artisan podman:setup inside a disposable container, for hosts that have Podman but not PHP. See Setting up without PHP on the host.
  • vendor/bin/lpod-secrets — prompts for and stores the Podman secrets an installed Quadlet unit needs.

lpod setup and lpod secrets are convenience aliases for the latter two — call vendor/bin/lpod-setup/vendor/bin/lpod-secrets directly if you'd rather skip the lpod wrapper.

vendor/bin/lpod SERVICE COMMAND [options] [arguments]

vendor/bin/lpod my-app up
vendor/bin/lpod my-app artisan queue:work
vendor/bin/lpod my-app shell

# Installing, secrets, and other Quadlet management (see below)
vendor/bin/lpod install frankenphp-octane/app.quadlets --replace
vendor/bin/lpod secrets app

See The lpod CLI for the full command reference (including install/secrets/remove/list/print/uninstall), shortening the call with an alias/PATH entry, and tips & tricks.

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

Disclaimer

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

The MIT License (MIT). Please see License File for more information.