# Portainer deployment Start here if you want the public alpha tracker online from Portainer. Recommended first alpha path: 1. If you do **not** have a Docker image in Gitea yet, use `meshnet-tracker-nobuild-stack.yml`. 2. After that works, create a Gitea **Container package** and switch Portainer to an image-based stack. 3. Do **not** create an npm package for deployment. This service is Python + Docker. For Portainer, the useful package is a Docker/OCI container image in Gitea Packages. This folder contains: | File | Use when | | --- | --- | | `meshnet-tracker-nobuild-stack.yml` | Easiest first deployment. No Docker registry. Downloads a repo tarball and installs at container start. | | `meshnet-tracker-stack.yml` | Cleaner long-term deployment. Uses `deploy/docker/Dockerfile` / a prebuilt container image. | | `meshnet-relay-only-stack.yml` | Optional relay-only deployment for a separate relay host/container. Not needed for the default alpha stack because the tracker embeds the relay. | | `../docker/Dockerfile` | Builds one image containing tracker + relay + contracts packages. | Recommended alpha architecture: - One `meshnet-tracker` container. - The tracker runs the relay in-process via `--embedded-relay`. - The relay implementation is still the shared `meshnet_relay.RelayServer` class, so a future relay-only node can be split out without changing the protocol. - Nginx Proxy Manager (or nginx/Caddy/Traefik) terminates TLS and routes `/v1`, `/dashboard`, `/ws`, and `/rpc` to the container. Important: the separate `meshnet-relay` container was not dropped as a capability. We removed it from the default alpha stack only to make first deployment simpler. Relay-only deployment remains supported via `meshnet-relay-only-stack.yml` or by running `meshnet-relay` from the same image. ## Option A — easiest today: no registry / no package Use `meshnet-tracker-nobuild-stack.yml` in Portainer. It starts from `python:3.12-slim`, downloads a source `.tar.gz`, installs `packages/tracker`, `packages/relay`, and `packages/contracts`, then starts the tracker with embedded relay. First boot is slower, but it avoids creating/pushing a package. Required Portainer environment variables: ```text SOURCE_TARBALL_URL=https://git.d-popov.com/popov/neuron-tai/archive/master.tar.gz PUBLIC_TRACKER_URL=https://ai.neuron.d-popov.com PUBLIC_PROXY_NETWORK=proxy_net ``` If your Gitea archive URL requires auth, either make an alpha release tarball downloadable to the Portainer host, or move to Option B and push a container image. Optional alpha/devnet variables: ```text STARTING_CREDIT=1 DEVNET_TOPUP=1 HEARTBEAT_TIMEOUT=30 ``` Set `STARTING_CREDIT=0` and `DEVNET_TOPUP=0` before any mainnet / real-money deployment. ## Option B — recommended long-term: Gitea Container package Gitea Packages supports a Docker/OCI container registry. The package to create is a **Container Registry** package, not npm. Gitea docs: - Overview: https://docs.gitea.com/usage/packages/overview/ - Container Registry: https://docs.gitea.com/usage/packages/container/ For this repo, use an image name like: ```text git.d-popov.com/popov/neuron-tai-tracker:alpha ``` or, if you prefer nested image names: ```text git.d-popov.com/popov/neuron-tai/meshnet-tracker-relay:alpha ``` Gitea image naming rule is: ```text {registry}/{owner}/{image}:{tag} ``` For us: ```text registry = git.d-popov.com owner = popov image = neuron-tai-tracker label = alpha ``` ### 1. Create a Gitea token In Gitea: 1. Open user settings. 2. Go to Applications / Access Tokens. 3. Create a token that can write packages for `popov`. 4. Copy it once and store it safely. Do not commit the token into this repo or into the Portainer stack file. ### 2. Login to the Gitea container registry From a machine with Docker and this repo checked out: ```bash docker login git.d-popov.com ``` Username: your Gitea username. Password: the Gitea access token. If using 2FA/OAuth, Gitea docs recommend using a personal access token instead of your password. ### 3. Build the image Run from repo root: ```bash docker build \ -f deploy/docker/Dockerfile \ -t git.d-popov.com/popov/neuron-tai-tracker:alpha \ . ``` ### 4. Push the image package to Gitea ```bash docker push git.d-popov.com/popov/neuron-tai-tracker:alpha ``` After this, Gitea should show the package under the `popov` user/org packages. ### 5. Use the image in Portainer In `meshnet-tracker-stack.yml`, replace the local build block: ```yaml build: context: ../.. dockerfile: deploy/docker/Dockerfile image: meshnet-tracker-relay:local ``` with: ```yaml image: git.d-popov.com/popov/neuron-tai-tracker:alpha ``` If the package is private, configure Portainer registry credentials for `git.d-popov.com`: 1. Portainer → Registries → Add registry. 2. Type: Custom registry. 3. Registry URL: `git.d-popov.com`. 4. Username: your Gitea username. 5. Password/token: the Gitea access token. 6. Save, then deploy the stack. ## Nginx Proxy Manager routing Use the Docker bridge network that your reverse proxy is already attached to. From the current Portainer network list, use: ```text PUBLIC_PROXY_NETWORK=proxy_net ``` Do **not** use Docker's `host` network for the normal Portainer/Nginx Proxy Manager setup. The stack relies on Docker DNS names such as `meshnet-tracker`, and those work when the tracker and reverse proxy share a bridge network like `proxy_net`. Host networking is only useful for a special manual deployment where the container binds directly on the host and the proxy forwards to `127.0.0.1:` or the host IP; that is less isolated and needs different compose settings (`network_mode: host`, no `networks:` block, and usually no service-name DNS). Create one Proxy Host for the public tracker domain. Default location `/`: ```text Scheme: http Forward Hostname/IP: meshnet-tracker Forward Port: 8081 Websockets Support: ON ``` Custom locations: | Location | Forward hostname | Forward port | WebSockets | | --- | --- | --- | --- | | `/ws` | `meshnet-tracker` | `8765` | ON | | `/rpc` | `meshnet-tracker` | `8765` | ON | Advanced tab if WebSocket upgrades fail: ```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; ``` ## Portainer variables For both stacks: ```text PUBLIC_TRACKER_URL=https://ai.neuron.d-popov.com PUBLIC_PROXY_NETWORK=proxy_net ``` For `meshnet-tracker-nobuild-stack.yml` only: ```text SOURCE_TARBALL_URL=https://git.d-popov.com/popov/neuron-tai/archive/master.tar.gz SOURCE_STRIP_COMPONENTS=1 ``` Useful optional variables: ```text PUBLIC_RELAY_URL=wss://ai.neuron.d-popov.com/ws HEARTBEAT_TIMEOUT=30 ENABLE_BILLING_DB=1 STARTING_CREDIT=1 DEVNET_TOPUP=1 ``` `PUBLIC_RELAY_URL` can usually be omitted; the stack derives it from `PUBLIC_TRACKER_URL` by changing `https://` to `wss://` and appending `/ws`. ## Verify deployment From outside the Docker host: ```bash curl -s https://ai.neuron.d-popov.com/v1/health curl -s https://ai.neuron.d-popov.com/v1/network/map | python3 -m json.tool ``` Expected in `/v1/network/map`: ```json { "relay_url": "wss://ai.neuron.d-popov.com/ws", "relay": { "mode": "embedded", "url": "wss://ai.neuron.d-popov.com/ws", "bind_host": "0.0.0.0", "bind_port": 8765 } } ``` Then start a node from any NAT/WSL2 machine: ```bash meshnet-node start --tracker https://ai.neuron.d-popov.com --model Qwen/Qwen2.5-0.5B-Instruct ``` The node should print: ```text Relay advertised by tracker — using outbound tunnel wss://ai.neuron.d-popov.com/ws Relay connected — wss://ai.neuron.d-popov.com/rpc/ ``` ## Quick answer: npm or Gitea package? Use a Gitea **Container package** for Portainer. Do not use npm unless we later ship a JavaScript frontend package or Node.js CLI. It would not help the tracker/relay deployment. Recommended sequence: 1. Deploy now with `meshnet-tracker-nobuild-stack.yml`. 2. Build/push `git.d-popov.com/popov/neuron-tai-tracker:alpha` as a Gitea Container package. 3. Switch Portainer to the image-based stack. 4. Later automate build/push in CI.