Skip to content

Latest commit

 

History

History
130 lines (99 loc) · 4.68 KB

File metadata and controls

130 lines (99 loc) · 4.68 KB

CLAUDE.md – proxypark project context

What is this?

proxypark is an open-source CLI tool (park) for local reverse-proxy management on macOS. It uses Traefik + dnsmasq + mkcert to give every local project a clean https://*.test domain with trusted certificates — no port conflicts, parallel development, Valet migration path.

Repo: git@github.com:McGo/proxypark.git License: MIT CLI command: park

Architecture decisions (from live testing)

These are hard-won lessons from the initial setup session. Do NOT change these without good reason:

File-provider only, no Docker socket

Traefik's Docker provider requires mounting /var/run/docker.sock. On macOS with Docker Desktop, this fails with empty API responses due to socket symlink issues (/var/run/docker.sock~/.docker/run/docker.sock). Even mounting the real path doesn't work reliably.

Decision: We use Traefik's file-provider exclusively. Each park link writes a YAML config to ~/.proxypark/dynamic/. Traefik watches the directory and picks up changes instantly.

Per-domain certificates, not wildcards

.test is on the Public Suffix List (PSL). Browsers (Firefox, Chrome) reject wildcard certs for PSL TLDs — *.test is treated like *.com. mkcert also doesn't support double wildcards (*.*.test throws "not a valid hostname").

Decision: We generate explicit per-domain certs. Every park link and park unlink calls regenerate_certs which collects all domains from link-*.yml files and runs mkcert with the full list. The cert file is always named wildcard.test.pem (for config stability) but contains SANs for each individual domain.

Traefik v3 syntax

Traefik v3 changed the HostRegexp syntax. The old v2 syntax HostRegexp({name:.+}.test) no longer works. The correct v3 syntax is:

rule: "HostRegexp(`.+\\.test`)"

Valet coexistence

Valet can coexist by running on port 8080. The park valet enable command creates a catchall router with priority: 1 (lowest). Explicit park link entries always win because Traefik assigns higher priority to more specific rules.

File structure

proxypark/
├── park               # Single-file Bash CLI (~1080 lines)
├── README.md
├── LICENSE            # MIT
├── CLAUDE.md          # This file
└── .gitignore

Runtime data (NOT in repo):

~/.proxypark/
├── docker-compose.yml
├── certs/
│   ├── wildcard.test.pem
│   └── wildcard.test-key.pem
└── dynamic/
    ├── tls.yml
    ├── valet.yml (optional)
    ├── link-*.yml
    └── link-docker-*.yml

Development guidelines

  • Single-file CLI: park is one Bash script. Keep it that way for now — no build step, no dependencies beyond Bash, mkcert, dnsmasq, Docker.
  • macOS only: We assume Homebrew, /etc/resolver/, open command, Apple Silicon + Intel paths. Linux support is a future goal, not a current constraint.
  • All state in ~/.proxypark/: The repo is stateless. You can rm -rf ~/.proxypark and park install to start fresh.
  • Cert regeneration is automatic: park link, park link:docker, and park unlink all call regenerate_certs and restart Traefik. Never require the user to manually run park certs.
  • Dot notation for subdomains: park link api.myapp 3000 replaces the old park link:sub. link:sub still works as legacy alias.
  • link:docker compose integration: After linking a Docker container, park link:docker checks the local docker-compose.yml for container_name and proxy network, and offers to add them automatically so the link survives docker compose down/up.
  • macOS grep compatibility: Never use grep -P (GNU Perl regex). Use sed for pattern extraction instead — BSD grep on macOS doesn't support -P.

Roadmap / next steps

Priority order for development:

  1. park doctor ✅ — Implemented. 16 checks with auto-fix (--fix flag).
  2. Zsh completionspark <TAB> for commands, park unlink <TAB> for link names.
  3. Homebrew tapbrew install McGo/tap/proxypark for easy distribution.
  4. park serve — Start a PHP built-in server or Vite dev server in CWD and auto-link.
  5. Docker provider (optional) — Re-add as opt-in if socket issues get resolved. The file-provider path must always work as primary.

Testing

Currently no automated tests. Manual testing workflow:

# Fresh install
park install
park status

# Link a service
park link testapp 8000
park list
curl -k https://testapp.test  # Should route to localhost:8000

# Unlink
park unlink testapp
park list

# Valet integration
park valet enable
park valet disable

# Clean teardown
park uninstall