deploy: add Docker relay container, nginx alternative, and CN mirror docs - #36
deploy: add Docker relay container, nginx alternative, and CN mirror docs#36Hachiwa0 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7ddf1d1dd3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| # Relay application code, deploy reference files, and the hash-locked | ||
| # dependency list (the installed wheels are the ones setup-vps.sh pins). | ||
| COPY cc_remote/ ./cc_remote/ | ||
| COPY deploy/ ./deploy/ |
There was a problem hiding this comment.
Exclude deploy/env.relay from the image
When users follow deploy/README.md and create deploy/env.relay with the login password, session secret, and wrapper token before building, this broad COPY deploy/ includes that file because neither .dockerignore nor .gitignore excludes it. The resulting image therefore contains all production credentials at /app/deploy/env.relay, exposing them to anyone who receives or can inspect the image; exclude the populated environment file and avoid copying deployment-only files into the runtime image.
Useful? React with 👍 / 👎.
| ports: | ||
| # Loopback-only publish: the host nginx/Caddy terminates the public TLS | ||
| # and WebSocket connection and proxies it to 127.0.0.1:8765. | ||
| - "127.0.0.1:8765:8765" |
There was a problem hiding this comment.
Preserve a loopback proxy peer through Docker
With the documented host-nginx topology and default Docker bridge networking, publishing host 127.0.0.1:8765 through this mapping does not make nginx appear as a loopback peer inside the container; Uvicorn therefore ignores X-Forwarded-Proto because cc_remote/relay/__main__.py trusts only 127.0.0.1,::1. The relay sees http instead of https, so the exact effective-target check in server.py rejects browser login and WebSocket Origins for the configured HTTPS PUBLIC_ORIGIN. Use a topology where the relay actually sees a loopback peer, or explicitly and narrowly trust the container bridge proxy.
AGENTS.md reference: AGENTS.md:L48-L55
Useful? React with 👍 / 👎.
| ssl_certificate /etc/letsencrypt/live/cc-remote.example.com/fullchain.pem; | ||
| ssl_certificate_key /etc/letsencrypt/live/cc-remote.example.com/privkey.pem; |
There was a problem hiding this comment.
Bootstrap the certificate before enabling the TLS server
On a fresh host these certificate files do not exist, so enabling this configuration makes nginx -t fail before nginx or certbot --nginx can serve the included ACME challenge. Conversely, the numbered instructions run certbot before installing the configuration, so the claimed challenge location is not yet present. Provide an HTTP-only bootstrap configuration or use certbot certonly --webroot first, then enable this TLS block.
Useful? React with 👍 / 👎.
| export UV_DEFAULT_INDEX=https://mirrors.aliyun.com/pypi/simple | ||
| # 2) Faster python-build-standalone runtime downloads (npmmirror) | ||
| export UV_PYTHON_INSTALL_MIRROR=https://registry.npmmirror.com/-/binary/python-build-standalone |
There was a problem hiding this comment.
Forward the uv mirror variables through sudo
This mirror recipe does not work for the documented Linux installation path: deploy/install.sh crosses into sudo env at lines 120–128 while forwarding only CC_REMOTE_INSTALL_USER and the optional password-file variable, so normal sudo environment filtering removes both exported UV_* values before the bundled uv runs. Local sudo --help identifies -E/--preserve-env as the option for retaining these variables; alternatively, add both variables to the explicit sudo_env array.
Useful? React with 👍 / 👎.
| If `install.sh` itself times out fetching the role bundle, pre-download the | ||
| release archive elsewhere and retry. When deploying the Relay in a Docker |
There was a problem hiding this comment.
Point install.sh at the pre-downloaded release
Pre-downloading the archive does not affect a retry: deploy/install.sh always creates a new temporary directory and fetches both the archive and SHA256SUMS from CC_REMOTE_RELEASE_BASE_URL, with no local-cache lookup or archive argument. Users whose GitHub download times out will therefore hit the same failing request; document downloading both files and setting CC_REMOTE_RELEASE_BASE_URL=file:///..., or add an explicit local-source option.
Useful? React with 👍 / 👎.
…trap, sudo env, release download)
What
Adds an official container deploy option for the Relay, an nginx reverse-proxy alternative to the managed Caddy, and mainland-China mirror guidance.
Why
The project currently ships only a systemd venv + managed Caddy path. On a memory-constrained VPS (or any host that already manages services/TLS itself), a container is the natural fit. This was built and verified end-to-end against a real deployment (relay in Docker behind nginx, wrapper connected over wss).
What's in it
deploy/Dockerfile— multi-stage: Node stage buildsweb/distfrom source (the repo does not track it), Python stage installs the same hash-locked wheelssetup-vps.shpins (--require-hashes --only-binary=:all: --no-binary=http-ece) and runspython -m cc_remote.relayas a non-rootccremoteuser (uid 10001, matching the systemd unit). Includes a HEALTHCHECK and parameterizedPIP_INDEX_URL/PIP_EXTRA_INDEX_URLbuild args for mirrors.deploy/docker-compose.yml— publishes the relay only to the host loopback (127.0.0.1:8765), a named volume for the SQLite device/Web Push state,read_onlyrootfs +tmpfs /tmp.deploy/env.relay.docker.example— container-adapted env template.deploy/nginx-reverse-proxy.conf.example— TLS + WebSocket front for hosts already running nginx; loopback-only requirement documented (the relay trusts forwarded transport metadata only from loopback peers)..dockerignoredeploy/README.mdcontainer + nginx section, CN mirror tips in README.md / README_en.md, changelog entries.Notes
http-eceis sdist-only on PyPI, so it is exempted with--no-binaryexactly as the official installer does.