2.1 KiB
macOS Docker Client Design
Goal
Add a simple macOS-friendly Docker client that behaves like the previous local proxy product: the user runs one container, opens a web UI, loads a subscription, chooses a server, and points macOS apps at 127.0.0.1:8080.
Product Shape
The client is not a transparent gateway. It must not require router changes, host networking, NET_ADMIN, iptables, ipset, or TProxy. The first-screen UI should explain the current proxy state, active server, and exact local proxy addresses. Gateway-only controls remain available only when the app runs in gateway mode.
Runtime Architecture
APP_MODE=client switches the config generator to proxy-only sing-box config:
- one
mixedinbound onPROXY_PORT; - no
tproxyinbound; - custom routing rules still apply before fallback;
proxyDefaultModecontrols the mixed proxy fallback and defaults to VPN;- generated configs still pass
sing-box checkbefore restart.
The client Docker image builds the React frontend inside Docker so macOS installation does not require local Node.js. Docker publishes only loopback ports:
127.0.0.1:3456for the UI;127.0.0.1:8080for HTTP/SOCKS proxy.
Installer
The macOS installer is a curl-friendly shell script. It checks macOS, Docker, Docker Compose, and Git, clones or updates the repository under ~/.vpn-proxy-client, then runs the client compose file with --build. It prints the UI URL, proxy URLs, and optional networksetup commands, but does not change system proxy settings automatically.
UI
Client mode gets a user-facing overview based on the old workflow:
- status: ready, stopped, not configured, applying, error;
- active server and traffic quota;
- copyable HTTP and SOCKS5 proxy URLs;
- short macOS setup commands;
- primary actions: load subscription, choose server, restart, stop.
Gateway terminology such as TProxy, devices, router, transparent fallback, and direct bypass cache is hidden in client mode.
Verification
Use node:test for server config behavior, then run:
npm test;npm run build;docker compose -f docker-compose.client.yml config.