Files
neuron-tai/docs/DEPLOY_PORTAINER.md
2026-07-02 23:07:41 +02:00

4.7 KiB

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:

docker network create npm_proxy
docker network connect npm_proxy <nginx-proxy-manager-container>

2. Portainer stack

Portainer → Stacks → Add stack → Repository.

Stack file:

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:

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.

ENABLE_BILLING_DB=1 makes billing public behavior active: /v1/chat/completions requires Authorization: Bearer <api-key>. Any key is accepted and starts with the configured starter credit; calls return 402 after that balance is exhausted. Set ENABLE_BILLING_DB=0 if existing unauthenticated clients must keep working during the first redeploy.

Optional Solana treasury settlement variables:

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:

meshnet-tracker  internal 8081
meshnet-relay    internal 8765

3. Nginx Proxy Manager

One Proxy Host for cloud.neuron.d-popov.com:

Forward Hostname/IP: meshnet-tracker
Forward Port:        8081
Websockets Support:  ON
SSL:                 Let's Encrypt + Force SSL

Custom locations on the same proxy host:

/ws   -> http://meshnet-relay:8765
/rpc  -> http://meshnet-relay:8765

Leave sub-folder forwarding empty.

If WebSockets fail, Advanced:

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

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:

curl -s https://cloud.neuron.d-popov.com/dashboard | head

Then open:

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.

meshnet-node start --tracker https://cloud.neuron.d-popov.com --model Qwen/Qwen2.5-0.5B-Instruct

Expected:

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:

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:

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.