188 lines
5.5 KiB
Markdown
188 lines
5.5 KiB
Markdown
# One-shot Portainer deploy: public tracker + relay
|
|
|
|
No Dockerfile, no custom image, no registry. Portainer runs `python:3.12-slim`, downloads this repo tarball, installs tracker/relay, and starts both services.
|
|
|
|
## 1. One-time host setup
|
|
|
|
DNS points to the Docker host, e.g. `cloud.neuron.d-popov.com`.
|
|
Firewall exposes only `80`, `443`, and admin SSH.
|
|
Nginx Proxy Manager and this stack share a Docker network, e.g. `npm_proxy`.
|
|
|
|
If needed:
|
|
|
|
```bash
|
|
docker network create npm_proxy
|
|
docker network connect npm_proxy <nginx-proxy-manager-container>
|
|
```
|
|
|
|
## 2. Portainer stack
|
|
|
|
Portainer → Stacks → Add stack → Repository.
|
|
|
|
Stack file:
|
|
|
|
```text
|
|
deploy/portainer/meshnet-tracker-nobuild-stack.yml
|
|
```
|
|
|
|
Deploy only after the current branch has been pushed. The stack passes the
|
|
current tracker billing flags (`--billing-db`, and optional treasury flags), so
|
|
an older remote `master.tar.gz` will crash on startup with unrecognized
|
|
arguments.
|
|
|
|
Variables:
|
|
|
|
```text
|
|
SOURCE_TARBALL_URL=https://git.d-popov.com/<owner>/<repo>/archive/master.tar.gz
|
|
PUBLIC_TRACKER_URL=https://cloud.neuron.d-popov.com
|
|
PUBLIC_PROXY_NETWORK=npm_proxy
|
|
CLUSTER_PEERS=https://ai.neuron.d-popov.com
|
|
PUBLIC_RELAY_URL=wss://cloud.neuron.d-popov.com/ws
|
|
HEARTBEAT_TIMEOUT=30
|
|
ENABLE_BILLING_DB=1
|
|
```
|
|
|
|
For first cloud-only test, use `CLUSTER_PEERS=`. Click **Deploy the stack**.
|
|
(`ai.neuron.d-popov.com` is publicly reachable, so two-tracker sync works over the
|
|
internet — but add it only after the cloud-only friends test proves out; two-peer
|
|
Raft adds moving parts without fault tolerance.)
|
|
|
|
`ENABLE_BILLING_DB=1` makes billing public behavior active: `/v1/chat/completions`
|
|
requires `Authorization: Bearer <sk-mesh-...>` — a real API key created through
|
|
an account (register on `/dashboard`, then "+ new key"); arbitrary bearer
|
|
strings are rejected with `401`. Calls return `402` once the key's balance is
|
|
exhausted. Set `ENABLE_BILLING_DB=0` if existing unauthenticated clients must
|
|
keep working during the first redeploy.
|
|
|
|
Credit variables (US-039/US-040):
|
|
|
|
```text
|
|
STARTING_CREDIT=1 # one-time Caller Credit (USDT) on an account's first key
|
|
DEVNET_TOPUP=1 # dashboard "+$N (devnet)" faucet button; 0 disables
|
|
```
|
|
|
|
Both default to **1** (devnet-friendly alpha). On any deployment holding a
|
|
mainnet treasury set both to 0 — the faucet mints client balance for free.
|
|
|
|
Optional Solana treasury settlement variables:
|
|
|
|
```text
|
|
SOLANA_RPC_URL=https://api.devnet.solana.com
|
|
USDT_MINT=<mock-usdt-mint-from-scripts/devnet_setup.py>
|
|
MESHNET_TREASURY_KEYPAIR_B64=<base64 of solana keypair JSON>
|
|
SETTLE_PERIOD=86400
|
|
PAYOUT_THRESHOLD=5
|
|
PAYOUT_DUST_FLOOR=0.01
|
|
```
|
|
|
|
Set all three treasury identity values together (`SOLANA_RPC_URL`, `USDT_MINT`,
|
|
`MESHNET_TREASURY_KEYPAIR_B64`) or leave all three empty. The stack writes the
|
|
decoded keypair into the tracker data volume at startup and passes it to
|
|
`meshnet-tracker`; do not put this key on relay-only hosts or non-settlement
|
|
trackers.
|
|
|
|
Expected containers:
|
|
|
|
```text
|
|
meshnet-tracker internal 8081
|
|
meshnet-relay internal 8765
|
|
```
|
|
|
|
## 3. Nginx Proxy Manager
|
|
|
|
One Proxy Host for `cloud.neuron.d-popov.com`:
|
|
|
|
```text
|
|
Forward Hostname/IP: meshnet-tracker
|
|
Forward Port: 8081
|
|
Websockets Support: ON
|
|
SSL: Let's Encrypt + Force SSL
|
|
```
|
|
|
|
Custom locations on the same proxy host:
|
|
|
|
```text
|
|
/ws -> http://meshnet-relay:8765
|
|
/rpc -> http://meshnet-relay:8765
|
|
```
|
|
|
|
Leave sub-folder forwarding empty.
|
|
|
|
**Required:** NPM custom locations do NOT inherit the proxy host's "Websockets
|
|
Support" toggle. Paste this into the **Advanced** box of *each* custom location
|
|
(`/ws` and `/rpc`), or every WebSocket handshake to the relay dies at nginx:
|
|
|
|
```nginx
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $http_connection;
|
|
proxy_read_timeout 3600s;
|
|
proxy_send_timeout 3600s;
|
|
```
|
|
|
|
## 4. Smoke test
|
|
|
|
```bash
|
|
curl -s https://cloud.neuron.d-popov.com/v1/health
|
|
curl -s https://cloud.neuron.d-popov.com/v1/network/map | python3 -m json.tool
|
|
curl -s https://cloud.neuron.d-popov.com/v1/raft/status | python3 -m json.tool
|
|
```
|
|
|
|
Plain curl to `/ws` or `/rpc/test-peer` may show `426 Upgrade Required`; OK. It must not show nginx `502`.
|
|
|
|
Dashboard:
|
|
|
|
```bash
|
|
curl -s https://cloud.neuron.d-popov.com/dashboard | head
|
|
```
|
|
|
|
Then open:
|
|
|
|
```text
|
|
https://cloud.neuron.d-popov.com/dashboard
|
|
```
|
|
|
|
The dashboard is served by the tracker through the same proxy host; no extra NPM
|
|
location is required.
|
|
|
|
If you previously deployed the build-image variant before `/var/lib/meshnet`
|
|
was created as the `meshnet` user, the named volume may already be root-owned.
|
|
Recreate that volume or chown it once before retrying the fixed image.
|
|
|
|
## 5. Start a node
|
|
|
|
`meshnet-node` is the worker/miner process. It will ask for a model and load a
|
|
model shard. Do not use it to test the tracker dashboard.
|
|
|
|
```bash
|
|
meshnet-node start --tracker https://cloud.neuron.d-popov.com --model Qwen/Qwen2.5-0.5B-Instruct
|
|
```
|
|
|
|
Expected:
|
|
|
|
```text
|
|
Relay advertised by tracker — using outbound tunnel wss://cloud.neuron.d-popov.com/ws
|
|
Relay connected — wss://cloud.neuron.d-popov.com/rpc/<peer_id>
|
|
```
|
|
|
|
## 6. Two tracker sync
|
|
|
|
Cloud stack:
|
|
|
|
```text
|
|
PUBLIC_TRACKER_URL=https://cloud.neuron.d-popov.com
|
|
CLUSTER_PEERS=https://ai.neuron.d-popov.com
|
|
PUBLIC_RELAY_URL=wss://cloud.neuron.d-popov.com/ws
|
|
```
|
|
|
|
Local tracker:
|
|
|
|
```bash
|
|
meshnet-tracker start --host 0.0.0.0 --port 8081 \
|
|
--self-url https://ai.neuron.d-popov.com \
|
|
--cluster-peers https://cloud.neuron.d-popov.com \
|
|
--relay-url wss://ai.neuron.d-popov.com/ws
|
|
```
|
|
|
|
Two Raft peers are enough for sync testing; real HA needs three trackers.
|