beyondcode / beyondcode/herd-community
[Bug]: Laravel Herd using wrong user group in php-fpm config
- Dominant language
- No language data
- Stars
- 122
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
### Platform
macOS
### Operating system version
MacOS Tahoe 26.0.1
### System architecture
Intel (x86)
### Herd Version
1.22.3
### PHP Version
_No response_
### Bug description
By default, PHP-FPM assumes that the current macOS user belongs to the system group called staff.
However, in some environments — especially managed or MDM-enrolled Macs — users are not part of the staff group.
This causes 502 Bad Gateway errors in Nginx because PHP-FPM sockets can’t be accessed by the running user.
You can manually fix this by editing the PHP-FPM config for each PHP version as described here [beyondcode/herd-community#10 (comment)](https://github.com/beyondcode/herd-community/issues/10#issuecomment-1648579131)
The problem is that Herd regenerates these config files every time you switch PHP versions, which means the manual changes are lost and have to be redone.
It would be great if Laravel Herd handled this automatically — it’s a small issue but a major headache for affected users.
Until that’s built in, here’s a simple workaround (courtesy of ChatGPT 😄) that automatically patches the PHP-FPM configs whenever Herd regenerates them.
# 🧰 Herd FPM Admin Patch — Fix PHP-FPM Group Issues Automatically on macOS
## 📖 Overview
This small utility fixes a recurring problem with **Laravel Herd** where PHP-FPM sockets are created with the wrong group permissions, resulting in **502 Bad Gateway** errors when switching PHP versions.
It installs two simple components:
1. **A Bash script** (`herd-fpm-admin-patch`) — fixes `group` permissions in Herd PHP-FPM config files.
2. **A LaunchAgent** — automatically runs the patch every time Herd regenerates its config.
After installation, your setup will **self-heal** whenever Herd changes PHP versions — no more manual edits.
---
## 🧠 The problem
When you switch PHP versions in Herd, it regenerates FPM pool configs such as:
```
~/Library/Application Support/Herd/config/fpm/8.4-fpm.conf
```
These contain:
```ini
group = staff
listen.group = staff
listen.mode = 0660
```
On many macOS setups — especially **managed or MDM-enrolled Macs** — your user account is **not in the `staff` group**.
When this happens, PHP-FPM fails to create its socket, and Nginx returns:
```
502 Bad Gateway
connect() to unix:/Users/.../herd84.sock failed (61: Connection refused)
```
---
## 💡 What this fix does
The patch ensures all Herd PHP-FPM configs use a valid group your user belongs to (e.g., `admin`).
Specifically, it:
- Changes
```ini
group = staff
listen.group = staff
```
→
```ini
group = admin
listen.group = admin
```
- Keeps
```ini
listen.mode = 0660
```
- Restarts Herd so changes take effect.
It’s **safe**, **idempotent**, and **automatic**.
---
## 🛠️ How to install
Copy and paste the following command block into your terminal:
```bash
# 1️⃣ Create the patch script
sudo tee /usr/local/bin/herd-fpm-admin-patch >/dev/null <<'SH'
#!/bin/sh
# herd-fpm-admin-patch (macOS)
# Patches Herd PHP-FPM pool files to use a specific socket group & mode, then restarts Herd.
#
# Env overrides:
# HERD_GROUP=admin # which group should own the FPM socket
# HERD_MODE=0660 # socket mode
#
# Usage:
# HERD_GROUP=admin HERD_MODE=0660 sh herd-fpm-admin-patch
#
# Description:
# - Scans all Herd PHP-FPM pool config files (e.g., 8.3-fpm.conf, 8.4-fpm.conf)
# - Replaces "group" and "listen.group" with HERD_GROUP
# - Ensures "listen.mode" matches HERD_MODE
# - Restarts Herd after applying changes
#
# Works around an issue where Herd sets group=staff by default, breaking sockets
# for users who aren’t in the staff group.
set -eu
HERD_GROUP="${HERD_GROUP:-admin}"
HERD_MODE="${HERD_MODE:-0660}"
HERD_BIN="$HOME/Library/Application Support/Herd/bin/herd"
echo "Scanning for FPM pool files…"
LIST="$(mktemp)"
find "$HOME/Library/Application Support/Herd" "/Library/Application Support/Herd" -maxdepth 6 -type f -name "*fpm*.conf" 2>/dev/null | sort -u > "$LIST" || true
[ -s "$LIST" ] || { echo "No *fpm*.conf files found."; rm -f "$LIST"; exit 0; }
CHANGED=0
while IFS= read -r f; do
[ -f "$f" ] || continue
echo "Checking: $f"
tmp="${f}.tmp.$$"
/usr/bin/awk -v G="$HERD_GROUP" -v M="$HERD_MODE" '
BEGIN { g=0; lg=0; lm=0 }
/^[[:space:]]*group[[:space:]]*=/ { print "group = " G; g=1; next }
/^[[:space:]]*listen\.group[[:space:]]*=/ { print "listen.group = " G; lg=1; next }
/^[[:space:]]*listen\.mode[[:space:]]*=/ { print "listen.mode = " M; lm=1; next }
{ print }
END {
if (!g) print "group = " G;
if (!lg) print "listen.group = " G;
if (!lm) print "listen.mode = " M;
}' "$f" > "$tmp"
if ! cmp -s "$f" "$tmp"; then
[ -w "$f" ] && mv "$tmp" "$f" || { echo " (not writable; using sudo)"; sudo mv "$tmp" "$f"; }
echo " → Patched"
CHANGED=1
else
rm -f "$tmp"
echo " (no changes)"
fi
done < "$LIST"
rm -f "$LIST"
if [ "$CHANGED" -eq 1 ]; then
echo "Changes applied. Restarting Herd services…"
if [ -x "$HERD_BIN" ]; then
"$HERD_BIN" stop && "$HERD_BIN" start || echo "Patched configs; restart via the Herd app."
else
echo "Herd CLI not found at: $HERD_BIN"
open -g -a Herd || true
fi
else
echo "No changes needed."
fi
SH
sudo chmod +x /usr/local/bin/herd-fpm-admin-patch
# 2️⃣ Create a LaunchAgent that auto-runs when Herd changes configs
mkdir -p "$HOME/Library/Logs" "$HOME/Library/LaunchAgents"
cat > "$HOME/Library/LaunchAgents/com.herd.fpm-admin-patch.plist" <
Label
com.herd.fpm-admin-patch
ProgramArguments
/bin/sh
-lc
/usr/local/bin/herd-fpm-admin-patch
EnvironmentVariables
PATH
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
RunAtLoad
WatchPaths
$HOME/Library/Application Support/Herd/config/fpm
$HOME/Library/Application Support/Herd/fpm
StandardOutPath
$HOME/Library/Logs/herd-fpm-admin-patch.out
StandardErrorPath
$HOME/Library/Logs/herd-fpm-admin-patch.err
PLIST
launchctl unload "$HOME/Library/LaunchAgents/com.herd.fpm-admin-patch.plist" 2>/dev/null || true
launchctl load "$HOME/Library/LaunchAgents/com.herd.fpm-admin-patch.plist"
echo "✅ Installed herd-fpm-admin-patch. It will now auto-fix FPM configs whenever Herd rewrites them."
```
---
## 🧾 Verify the installation
Run:
```bash
launchctl list | grep herd-fpm
```
You should see:
```
com.herd.fpm-admin-patch
```
Check logs:
```bash
tail -n 20 ~/Library/Logs/herd-fpm-admin-patch.out
```
---
## 🧹 To uninstall
```bash
launchctl unload ~/Library/LaunchAgents/com.herd.fpm-admin-patch.plist
rm -f ~/Library/LaunchAgents/com.herd.fpm-admin-patch.plist
sudo rm -f /usr/local/bin/herd-fpm-admin-patch
```
---
## 💡 Recommendations for Herd maintainers
1. Detect if the user belongs to `staff` before setting `group = staff`.
2. Default to the user’s **primary group** if not.
3. Add a configurable override (e.g. “Preferred FPM Group”) in settings.
4. Introduce `herd restart --all` to restart all PHP-FPM pools.
---
## ✅ Result
After installation:
- No more 502 Bad Gateway errors after PHP version changes.
- PHP-FPM sockets always use the correct group (`admin`).
- Fully automatic — patches itself whenever Herd regenerates configs.
### Steps to reproduce
_No response_
### Relevant log output
```shell
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.