netanalyzer/docker/remote-agent/deploy/README.md
Joseph McQueen 7081221352 feat(agent): support corporate CA bundles for wss:// TLS verification
Add WS_TLS_CA_FILE and WS_TLS_REJECT_UNAUTHORIZED so the remote agent can
trust internal PKI chains instead of failing with "unable to verify the
first certificate". Apply the same TLS options to proxied HTTPS calls and
document CA bundle mounting in compose and deploy READMEs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 14:00:46 -04:00

147 lines
5.4 KiB
Markdown

# StoreHealthAnalyzer Remote Agent — Deploy Bundle
This ZIP is a self-contained deployment bundle for the StoreHealthAnalyzer
remote agent. Extract it, run `install.sh`, fill in your `.env`, and the
agent will start as a Docker container.
## What's in the bundle
| File | Purpose |
| --- | --- |
| `sha-remote-agent-<version>.tar.gz` | The Docker image, saved via `docker save`. |
| `docker-compose.yml` | Runtime-only compose file (no build step; references the loaded image). |
| `install.sh` | Verifies checksum, loads the image, seeds `.env`, starts the container. |
| `.env.example` | Template — copied to `.env` on first run for you to fill in. |
| `SHA256SUMS` | Integrity check for the image tarball. |
| `VERSION` | Plain-text version marker used by `install.sh` and `docker-compose.yml`. |
| `README.md` | This file. |
## Prerequisites (on the remote host)
- Docker 20.10+ with the daemon running.
- Docker Compose — either the modern `docker compose` plugin (v2) or the
legacy `docker-compose` binary. `install.sh` auto-detects.
- Whichever user runs `install.sh` needs permission to talk to the Docker
daemon (member of the `docker` group, or run under `sudo`).
- Outbound network access from the host to:
- The main StoreHealthAnalyzer server (`WS_URL`).
- The internal APIs the agent proxies for (SIW, MDM, etc.).
## Install / start
```bash
unzip sha-remote-agent-<version>.zip
cd sha-remote-agent-<version>
./install.sh
```
On the first run `install.sh` will:
1. Verify the SHA-256 of the image tarball against `SHA256SUMS`.
2. Load the image into Docker (skipped on subsequent runs if the image is
already present).
3. Copy `.env.example``.env` and stop, asking you to fill it in.
Fill in `.env`:
```bash
vi .env # set WS_URL and WS_TOKEN
```
Then re-run:
```bash
./install.sh
```
That last run will start the container (`docker compose up -d`) and print
the log-tail command.
## Day-to-day operations
```bash
docker compose logs -f # tail the agent logs
docker compose ps # show container status
docker compose restart # cycle it
docker compose down # stop and remove the container
docker compose up -d # bring it back up
```
Healthy startup looks like:
```
🔄 Connecting to wss://.../ws...
✅ Remote Agent connected to StoreHealthAnalyzer
```
## Upgrading
When you receive a newer ZIP:
```bash
# Optional: back up your existing config
cp -a <old-version-folder>/.env ./sha-remote-agent-<new-version>-env.bak
# Stop the old container
cd <old-version-folder> && docker compose down && cd ..
# Extract and start the new one
unzip sha-remote-agent-<new-version>.zip
cp <old-version-folder>/.env sha-remote-agent-<new-version>/.env
cd sha-remote-agent-<new-version>
./install.sh
```
The old image stays in Docker's local cache until you `docker image prune`
it — handy if you need to roll back quickly.
## Troubleshooting
- **"Cannot talk to the Docker daemon"** — either Docker isn't running or
your user isn't in the `docker` group. Try `sudo ./install.sh` or add
yourself to the group: `sudo usermod -aG docker $USER` and log back in.
- **"Checksum verification FAILED"** — the ZIP was corrupted in transit.
Re-transfer.
- **"exec /sbin/tini: exec format error"** or **"Image architecture
does not match this host"** — the ZIP was built for the wrong CPU
architecture (typically an Apple Silicon Mac produced an `arm64` image
for an `x86_64` Linux host). `install.sh` catches this and prints the
exact rebuild command; ask your build operator to `git pull` first
(to pick up the fixed cross-arch build) and then run:
```
./docker/remote-agent/package.sh --platform linux/amd64
```
(or `linux/arm64` if this host is ARM — run `uname -m` to check:
`x86_64``linux/amd64`, `aarch64``linux/arm64`.)
Note that `install.sh` **always** re-runs `docker load` on the bundled
tarball, so a stale image left from an earlier wrong-arch attempt at the
same version tag will be transparently replaced when you install a
corrected bundle — no need to `docker rmi` by hand.
- **Agent connects, then disconnects immediately** — `WS_TOKEN` doesn't
match the server. Fix in `.env`, then `docker compose restart`.
- **Agent never connects** — check `WS_URL` (correct hostname, correct
scheme `ws://` vs `wss://`) and that there's no firewall between this
host and the server.
- **`unable to verify the first certificate`** — the server's TLS cert is
signed by a corporate/private CA that Node doesn't trust by default. **Do
not** leave this broken; provide the CA chain instead of ignoring TLS:
1. Ask your PKI team (or export from the browser) for the **root** and
**intermediate** CA certificates in PEM format.
2. Concatenate into one bundle:
```bash
cat root-ca.pem intermediate-ca.pem > certs/ca-bundle.pem
```
3. On this host, next to `docker-compose.yml`:
```bash
mkdir -p certs
# copy ca-bundle.pem into certs/
```
4. Uncomment the `volumes` + `environment` block in `docker-compose.yml`
(or add to `.env`: `WS_TLS_CA_FILE=/certs/ca-bundle.pem` and mount the
file in compose).
5. `docker compose up -d` (or `./install.sh` on first deploy).
Temporary workaround only on a fully trusted network:
`WS_TLS_REJECT_UNAUTHORIZED=false` in `.env`. This disables verification
for both the websocket and any HTTPS APIs the agent proxies.