Skip to content

feat(shell): bake zsh + starship into PHP-FPM image#358

Open
geodro wants to merge 1 commit into
mainfrom
feat/zsh-container-shell
Open

feat(shell): bake zsh + starship into PHP-FPM image#358
geodro wants to merge 1 commit into
mainfrom
feat/zsh-container-shell

Conversation

@geodro
Copy link
Copy Markdown
Owner

@geodro geodro commented May 15, 2026

Summary

The lerd PHP-FPM image now drops into zsh with starship instead of bare sh when you run lerd shell (or hit the TUI shell action). Container ships its own self-contained config so the experience is predictable across machines.

What's in the image: zsh, starship, eza, bat, fzf, zoxide. The lerd-shipped /etc/zsh/zshrc wires up persistent history (per PHP version, under ~/.local/share/lerd/shell-state/php-<ver>/zsh/), enables completion with compinit -u, and inits starship. The FPM quadlet pins HostName= to the host's hostname so the prompt reads root@your-machine, not an opaque container id.

Host shell config is intentionally not mounted. An earlier round of this branch tried to bind-mount ~/.config/fish and ~/.zshrc for an OrbStack-like inherit-your-prompt experience, but every customised host config has its own pile of distro-specific source paths and binaries that simply don't exist inside alpine, so the container shell would fire off a cascade of "no such file or directory" errors on every login. Cleaner to ship one good environment than to play whack-a-mole.

After upgrading, existing users need to rebuild their PHP images (lerd php:rebuild <ver>) and recreate the FPM container (systemctl --user daemon-reload && podman rm -f lerd-php<short>-fpm && systemctl --user start lerd-php<short>-fpm) to pick up the new layer and the regenerated quadlet.

`lerd shell` and the TUI shell action previously dropped into bare `sh`,
which made the in-container experience feel like a different planet from
the host. The PHP-FPM image now ships zsh with a self-contained config
(starship prompt, `compinit -u`, persistent history under
`~/.local/share/lerd/shell-state/php-<ver>/zsh/`) and a handful of modern
CLI tools (eza, bat, fzf, zoxide). The quadlet sets `HostName=` to the
host's hostname so the prompt reads `root@your-machine` instead of an
opaque container id, and the renderer mounts the per-version zsh history
dir read-write so commands survive container rebuilds.
`InteractiveShellScript()` picks zsh in the FPM image and falls back
through bash to sh for other containers.

The shell environment is deliberately isolated from the host's
`~/.zshrc` and `~/.config/fish`. An earlier draft mounted those (first
read-only, then with podman's overlay flag for fish_variables writes),
but every customised host config introduced its own cascade of "no such
file or directory" errors as it tried to source distro-specific paths
the alpine container had never heard of. The container shell is its own
world now, consistent across every machine and contributor.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant