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

Đang mở Phù hợp với người mới
#1,575 1 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Python
Star
912
Fork
234
Merge trung bình
1 ngày 11 giờ
Pull request đã merge (30 ngày)
62

Mô tả

## 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.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Start at scripts/prepare-log-dirs.sh lines 17-20 where OWNER_UID/GID and DIR_MODE are set, then inspect docker-compose.yml mount points for registry, auth-server, and mcpgw under that log path. Reproduce on macOS with `docker compose down -v` and `./build_and_run.sh` to confirm mount and startup failure. Verify completion by rerunning startup and confirming services come up, no permission-denied log errors, and `curl localhost/health` responds. If touching the rendered-config fallback note, inspect registry/core/nginx_service.py (around 627 and 1299) and docker/nginx_rev_proxy_http_only.conf:93 to ensure unresolved `{{...}}` templates are not left as primary failure output.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
docker, nginx, python, shell
Lĩnh vực
devops
Loại issue
Lỗi
Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
70/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.