Files
neuron-tai/deploy/portainer/README.md
2026-07-09 09:21:56 +02:00

8.0 KiB

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:

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:

STARTING_CREDIT=1
DEVNET_TOPUP=1
HEARTBEAT_TIMEOUT=30

Set STARTING_CREDIT=0 and DEVNET_TOPUP=0 before any mainnet / real-money deployment.

Gitea Packages supports a Docker/OCI container registry. The package to create is a Container Registry package, not npm.

Gitea docs:

For this repo, use an image name like:

git.d-popov.com/popov/neuron-tai-tracker:alpha

or, if you prefer nested image names:

git.d-popov.com/popov/neuron-tai/meshnet-tracker-relay:alpha

Gitea image naming rule is:

{registry}/{owner}/{image}:{tag}

For us:

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:

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:

docker build \
  -f deploy/docker/Dockerfile \
  -t git.d-popov.com/popov/neuron-tai-tracker:alpha \
  .

4. Push the image package to Gitea

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:

build:
  context: ../..
  dockerfile: deploy/docker/Dockerfile
image: meshnet-tracker-relay:local

with:

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:

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:<port> 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 /:

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:

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:

PUBLIC_TRACKER_URL=https://ai.neuron.d-popov.com
PUBLIC_PROXY_NETWORK=proxy_net

For meshnet-tracker-nobuild-stack.yml only:

SOURCE_TARBALL_URL=https://git.d-popov.com/popov/neuron-tai/archive/master.tar.gz
SOURCE_STRIP_COMPONENTS=1

Useful optional variables:

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:

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:

{
  "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:

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

The node should print:

Relay advertised by tracker — using outbound tunnel wss://ai.neuron.d-popov.com/ws
Relay connected — wss://ai.neuron.d-popov.com/rpc/<peer_id>

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.