agentic-community / agentic-community/mcp-gateway-registry
macOS: prepare-log-dirs.sh 0750/uid-1000 blocks the bind mount and nginx logging, so registry/auth-server/mcpgw never serve
- Lingua principale
- Python
- Stelle
- 911
- Fork
- 234
- Merge medio
- 1g 11h
- PR unite (30g)
- 62
Descrizione
## Summary
On Docker Desktop for Mac, `scripts/prepare-log-dirs.sh` leaves `/var/log/containers/ai-registry` in a state the containers cannot write to, which blocks the registry, auth-server, and mcpgw services from starting. A from-scratch macOS install cannot reach a serving state without manual `chmod` intervention.
The script ([lines 17-20](https://github.com/agentic-community/mcp-gateway-registry/blob/main/scripts/prepare-log-dirs.sh#L17-L20)) creates the directory owned `1000:1000` with mode `0750`:
```bash
OWNER_UID="${LOG_DIR_OWNER_UID:-1000}"
OWNER_GID="${LOG_DIR_OWNER_GID:-1000}"
DIR_MODE="${LOG_DIR_MODE:-0750}"
```
That is correct on a Linux host, where the container's uid 1000 and the host's uid 1000 are the same identity. On Docker Desktop for Mac they are not: the VM's file-sharing layer (virtiofs/gRPC-FUSE) maps host ownership in a way that does not grant the container's uid-1000 process write access, even though `ls` *inside* the container cosmetically reports `appuser:appuser`.
## Failure sequence observed
Three services bind-mount this path (`docker-compose.yml` lines 513, 762, 829). The failure cascades in two distinct stages.
**Stage 1 — the bind mount itself fails.** With mode `0750`, the Docker daemon cannot traverse into the directory to set up the mount:
```
Error response from daemon: error while creating mount source path
'/host_mnt/private/var/log/containers/ai-registry':
mkdir /host_mnt/private/var/log/containers/ai-registry: permission denied
[ERROR] Failed to start remaining services
```
`registry`, `auth-server`, and `mcpgw-server` never start. Every other container comes up healthy, which makes this look like a service-specific bug rather than a shared mount problem.
**Stage 2 — nginx cannot open its logs, and the config is left unrendered.** After widening the directory to `0755` the mount succeeds and the containers start, but nginx still cannot write:
```
[emerg] open() "/var/log/containers/ai-registry/nginx-access.log" failed (13: Permission denied)
nginx: configuration file /etc/nginx/nginx.conf test failed
```
`nginx_service.py` then does the right thing and refuses the candidate config ([line 627](https://github.com/agentic-community/mcp-gateway-registry/blob/main/registry/core/nginx_service.py#L627), "restoring last-good config"). But on a **first** install there is no last-good config, so what remains on disk is the raw template — including the unsubstituted placeholder from [`docker/nginx_rev_proxy_http_only.conf:93`](https://github.com/agentic-community/mcp-gateway-registry/blob/main/docker/nginx_rev_proxy_http_only.conf#L93):
```
unexpected "{" in /etc/nginx/conf.d/nginx_rev_proxy.conf:93
```
The reported symptom is therefore an *nginx syntax error on a template placeholder*, several layers removed from the actual cause (a log directory permission). `{{REAL_IP_CONFIG}}` is normally substituted at [nginx_service.py:1299](https://github.com/agentic-community/mcp-gateway-registry/blob/main/registry/core/nginx_service.py#L1299); it survives only because the rendered candidate was rejected.
Net effect: `http://localhost/` and `http://localhost/health` return no response at all (curl exit 000, nothing listening behind the published port).
## Reproduction
macOS with Docker Desktop, from a clean state:
```bash
docker compose down -v
rm -rf .oauth-tokens/ .env
# ... configure .env, init keycloak, create agents ...
./build_and_run.sh
```
Observed on Docker version 29.2.0, macOS (Darwin 25.5.0), Docker Desktop with the default file-sharing implementation.
## Workaround
```bash
sudo chmod -R 0777 /var/log/containers/ai-registry
docker compose restart registry
```
The `-R` matters: widening only the directory fixes the mount (stage 1) but not nginx's ability to truncate pre-existing log *files* left by an earlier run (stage 2).
## Why I have not sent a patch
The right fix depends on intent I would rather not guess at:
1. **`0777` is the pragmatic local-dev answer** but is wrong to ship as a default for the Linux/production path, where `0750` is deliberate.
2. **The script's header explicitly ties the ownership model to Splunk forwarders** ("so customer Splunk forwarders can ingest the .log files directly"), so loosening ownership may have consequences beyond this bind mount.
3. **A macOS-conditional branch** (`if [[ "$(uname)" == "Darwin" ]]`) would keep Linux behavior intact, but the maintainers may prefer a named docker volume for the compose path instead of a host bind mount, which would sidestep uid mapping entirely.
4. The `LOG_DIR_MODE` env var already exists as an override hook, so documenting `LOG_DIR_MODE=0777` for macOS in the setup guides may be sufficient without any code change.
Happy to send a PR for whichever of these you prefer.
## Secondary observation
Independent of the permission question: when `nginx -t` rejects the candidate on a **first** install, the fallback leaves an unrenderable template on disk and the resulting error message points at a template placeholder rather than the real cause. Failing with the underlying `nginx -t` reason (which *is* logged just above) as the primary error, or refusing to install a config that still contains `{{` placeholders, would make this class of problem far easier to diagnose. I can file that separately if useful.
Guida per i contributori
Apri la guida per i contributori
Valutazione
Questa issue non è ancora stata valutata.