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
podman-lpod
foxws/laravel-podman
claude-code
lpod
podman-quadlet
systemd
devcontainer
artisan
testing
xdebug

Run Artisan, Composer, Node, tests and shell commands inside the app's Podman Quadlet containers with lpod, and manage those services (start, stop, install, secrets). Use when the project uses foxws/laravel-podman and you need to run anything in the app container or control its services.

Install
php artisan boost:add-skill foxws/laravel-podman

Save this content to: .claude/skills/podman-lpod/SKILL.md

# Running commands with lpod

This app runs as [Podman Quadlet](https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html) services managed by systemd. [`lpod`](https://github.com/foxws/lpod) is the CLI for them. Run PHP, Composer and Node through `lpod` so they use the container's versions and extensions, not the host's.

## Usage

```bash
lpod SERVICE COMMAND [arguments]
```

- `SERVICE` is the plain service name: the app (the kebab-cased `PODMAN_QUADLET_PREFIX`, which defaults to `APP_NAME`) or a service like `pgsql`. Don't add the `systemd-` prefix; `lpod` does that.
- Unknown commands are passed on to `podman`.
- Run `lpod list` to see the installed services.

## Inside a devcontainer

Check first whether you're in the package's devcontainer: `/run/.containerenv` exists or `REMOTE_CONTAINERS=true` is set, and `command -v lpod` finds nothing. There is no Podman or systemd in there, on purpose. Don't install them, and don't try Podman in Podman or mounting the host's Podman socket.

- Run PHP, Composer, Node and tests directly (`php artisan test`, `composer install`, `pnpm build`). The devcontainer has the same tools and joins the app's `systemd-{application}` network, so the database and cache hosts in `.env` work from it.
- `php artisan podman:generate` and `podman:setup` work there too. The devcontainer sets `PODMAN_WORKING_PATH` to the host path, so the rendered `Volume=` lines point at the host's working copy, not `/app`.
- `lpod`, `podman` (including `podman run` and `podman volume`) and `journalctl` act on the host's services. Don't run them, and don't work around that. List the exact commands for the user to run in a host terminal, from the project folder, and wait for their output.
- An `lpod my-app ...` command in this skill or another one becomes the plain command in the devcontainer: `lpod my-app artisan migrate` is `php artisan migrate`. Lifecycle, install, `secrets`, `idle` and `xdebug` commands stay on the host.

## In the app container

```bash
lpod my-app artisan migrate          # also: art, a
lpod my-app composer require foo/bar
lpod my-app php -v
lpod my-app tinker
lpod my-app debug queue:work         # Artisan with Xdebug enabled
lpod my-app xdebug on | off          # Xdebug for web requests (development image), restarts the app

lpod my-app test                     # php artisan test
lpod my-app pest --filter=UserTest
lpod my-app phpunit
lpod my-app pint

lpod my-app pnpm install             # also: node, npm, yarn, bun, npx, pnpx, bunx
lpod my-app bin phpstan              # ./vendor/bin/phpstan

lpod my-app run CMD                  # any command
lpod my-app shell                    # interactive shell; root-shell for root
```

Commands run as the host user (`APP_USER`, default `$(id -u)`). `lpod` loads `.env` and `.env.$APP_ENV` from the current directory.

## Service lifecycle

```bash
lpod my-app up | down | restart | status
lpod my-app secrets                  # prompt for the unit's Secret= values
lpod my-app open                     # open APP_URL in the browser
```

## Troubleshooting the host

Run `lpod doctor` when services don't start or the proxy doesn't answer. It checks Podman, systemd, linger, subordinate IDs, unprivileged ports, leftover `lpod-idle@` timers, the proxy's certificate, `APP_URL` and failed services, and prints fixes. Fixes with `sudo` are for the user to run.

## Installing rendered services

The Artisan commands only render files into `podman/` (don't commit it). `lpod` installs them:

```bash
php artisan podman:generate development
lpod install development/app.quadlets --replace
lpod reload                          # systemctl daemon-reload
lpod print my-app                    # show the generated systemd unit
```

After changing a `.quadlets` file or its template, regenerate and reinstall with `--replace`, then restart the service.

## On-demand idle check

The idle check comes with the on-demand socket: `lpod install ondemand/my-app-ondemand.socket --replace` installs and starts it. There's no separate enable step. It's the `[email protected]`/`[email protected]` template shared by every app on the host, run as `laravel-idle@my-app`, with the app's settings in the drop-in `[email protected]/idle.conf` (lpod v3.1.0 and later).

```bash
lpod idle my-app                     # run the check once (lpod v3.0.0 and later)
journalctl --user -u laravel-idle@my-app
```

The workers it checks and stops are set with `PODMAN_ONDEMAND_IDLE_WORKERS` (default `queue,horizon`); regenerate the `ondemand` preset and reinstall the socket after changing it. `lpod idle disable` only turns off the `lpod-idle@` timer of lpod releases before v3.0.0, and `lpod idle enable` only prints how to install the socket.

## Installing and upgrading lpod

```bash
curl -fsSL https://github.com/foxws/lpod/releases/latest/download/install.sh | bash
lpod --version
lpod self-update                     # v2.2.0 and later
```

## Destructive commands

`lpod remove NAME` and `lpod uninstall APPLICATION` delete the service's Podman volumes (databases, uploads, search indexes). There is no undo. Never run them without the user's explicit confirmation. Offer a backup first:

```bash
podman volume export my-app-pgsql -o pgsql-backup.tar
lpod my-app-pgsql run sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB"' > backup.sql
```

Check the real volume name with `podman volume ls` before exporting.

Running commands with lpod

This app runs as Podman Quadlet services managed by systemd. lpod is the CLI for them. Run PHP, Composer and Node through lpod so they use the container's versions and extensions, not the host's.

Usage

lpod SERVICE COMMAND [arguments]
  • SERVICE is the plain service name: the app (the kebab-cased PODMAN_QUADLET_PREFIX, which defaults to APP_NAME) or a service like pgsql. Don't add the systemd- prefix; lpod does that.
  • Unknown commands are passed on to podman.
  • Run lpod list to see the installed services.

Inside a devcontainer

Check first whether you're in the package's devcontainer: /run/.containerenv exists or REMOTE_CONTAINERS=true is set, and command -v lpod finds nothing. There is no Podman or systemd in there, on purpose. Don't install them, and don't try Podman in Podman or mounting the host's Podman socket.

  • Run PHP, Composer, Node and tests directly (php artisan test, composer install, pnpm build). The devcontainer has the same tools and joins the app's systemd-{application} network, so the database and cache hosts in .env work from it.
  • php artisan podman:generate and podman:setup work there too. The devcontainer sets PODMAN_WORKING_PATH to the host path, so the rendered Volume= lines point at the host's working copy, not /app.
  • lpod, podman (including podman run and podman volume) and journalctl act on the host's services. Don't run them, and don't work around that. List the exact commands for the user to run in a host terminal, from the project folder, and wait for their output.
  • An lpod my-app ... command in this skill or another one becomes the plain command in the devcontainer: lpod my-app artisan migrate is php artisan migrate. Lifecycle, install, secrets, idle and xdebug commands stay on the host.

In the app container

lpod my-app artisan migrate          # also: art, a
lpod my-app composer require foo/bar
lpod my-app php -v
lpod my-app tinker
lpod my-app debug queue:work         # Artisan with Xdebug enabled
lpod my-app xdebug on | off          # Xdebug for web requests (development image), restarts the app

lpod my-app test                     # php artisan test
lpod my-app pest --filter=UserTest
lpod my-app phpunit
lpod my-app pint

lpod my-app pnpm install             # also: node, npm, yarn, bun, npx, pnpx, bunx
lpod my-app bin phpstan              # ./vendor/bin/phpstan

lpod my-app run CMD                  # any command
lpod my-app shell                    # interactive shell; root-shell for root

Commands run as the host user (APP_USER, default $(id -u)). lpod loads .env and .env.$APP_ENV from the current directory.

Service lifecycle

lpod my-app up | down | restart | status
lpod my-app secrets                  # prompt for the unit's Secret= values
lpod my-app open                     # open APP_URL in the browser

Troubleshooting the host

Run lpod doctor when services don't start or the proxy doesn't answer. It checks Podman, systemd, linger, subordinate IDs, unprivileged ports, leftover lpod-idle@ timers, the proxy's certificate, APP_URL and failed services, and prints fixes. Fixes with sudo are for the user to run.

Installing rendered services

The Artisan commands only render files into podman/ (don't commit it). lpod installs them:

php artisan podman:generate development
lpod install development/app.quadlets --replace
lpod reload                          # systemctl daemon-reload
lpod print my-app                    # show the generated systemd unit

After changing a .quadlets file or its template, regenerate and reinstall with --replace, then restart the service.

On-demand idle check

The idle check comes with the on-demand socket: lpod install ondemand/my-app-ondemand.socket --replace installs and starts it. There's no separate enable step. It's the [email protected]/[email protected] template shared by every app on the host, run as laravel-idle@my-app, with the app's settings in the drop-in [email protected]/idle.conf (lpod v3.1.0 and later).

lpod idle my-app                     # run the check once (lpod v3.0.0 and later)
journalctl --user -u laravel-idle@my-app

The workers it checks and stops are set with PODMAN_ONDEMAND_IDLE_WORKERS (default queue,horizon); regenerate the ondemand preset and reinstall the socket after changing it. lpod idle disable only turns off the lpod-idle@ timer of lpod releases before v3.0.0, and lpod idle enable only prints how to install the socket.

Installing and upgrading lpod

curl -fsSL https://github.com/foxws/lpod/releases/latest/download/install.sh | bash
lpod --version
lpod self-update                     # v2.2.0 and later

Destructive commands

lpod remove NAME and lpod uninstall APPLICATION delete the service's Podman volumes (databases, uploads, search indexes). There is no undo. Never run them without the user's explicit confirmation. Offer a backup first:

podman volume export my-app-pgsql -o pgsql-backup.tar
lpod my-app-pgsql run sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB"' > backup.sql

Check the real volume name with podman volume ls before exporting.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core