Meshcore API is a Docker-only FastAPI service that exposes the meshcore_py capabilities as REST endpoints. It keeps a single MeshCore node online, forwards commands to the device, and surfaces inbound traffic via queues and optional webhooks.
Repository layout:
app/– FastAPI application, routes, queue/webhook helpers, configdocker/– Dockerfile, Compose/stack definitions,.env.examplerequirements.txt,LICENSE,README.md
- Async MeshCore client with auto-reconnect, retrying startup loop, and channel provisioning based on
.env - Static Bearer token auth (
Authorization: Bearer <API_TOKEN>) for every route - Dual event intake: TTL ring-buffer queues for polling plus webhook push with HMAC-SHA256 signatures and configurable retries
- Single Compose file that covers serial, BLE, and TCP deployments (host networking + privileged container with optional USB pass-through)
-
Copy the example env file inside
docker/and fill in the values that apply to your setup:cp docker/.env.example docker/.env
Key variables:
API_TOKEN: static bearer secret used by every client requestDEVICE_NAME: broadcast name reported to nodesCONNECTION_TYPE:serial,ble, ortcp- Serial mode: set
SERIAL_PORT,SERIAL_DEVICE,SERIAL_BAUD - BLE mode: set
BLE_ADDRESS(and optionalBLE_PIN) - TCP mode: set
TCP_HOST,TCP_PORT - Channels:
CHANNEL_<N>=NAME:PSK[:IDX](must includeCHANNEL_0) - Webhooks:
WEBHOOK_URL,WEBHOOK_SECRET,WEBHOOK_RETRY,WEBHOOK_RETRY_DELAY
Connection mode (XOR): exactly one transport may be active. If you set
CONNECTION_TYPE=serial, leave the BLE/TCP variables empty; likewise for BLE and TCP. Mixing connection blocks leads to undefined behavior and the container is expected to refuse to start once validation is in place. -
Generate a secure API token (32+ hex chars keeps things simple):
openssl rand -hex 32 # copy result into API_TOKENHex output avoids problematic characters. If you craft your own token make sure it does not contain
#, spaces, or shell-sensitive characters unless you wrap the value in quotes inside.env.
docker compose \
--env-file docker/.env \
-f docker/docker-compose.yml \
up --build
- Builds the image with
docker/Dockerfile(context..) - Runs the container as
meshcore-api, host network + privileged - Exposes the FastAPI service on
http://localhost:${API_PORT}(default 8000) - USB users set
SERIAL_DEVICE=/dev/ttyUSB0(or your actual path). Leave the variable empty if you do not need passthrough. - BLE/TCP deployments leave unrelated connection variables blank to honor the XOR rule.
Deploy the same container via docker/stack.yml (copy docker/.env.example to docker/.env first):
docker stack deploy -c docker/stack.yml meshcore-api
Remove the stack with docker stack rm meshcore-api when you are done.
- Merge your changes to
master. - Tag the commit with the next semantic version (numbers only, e.g.
0.0.1):git tag 0.0.1 git push origin 0.0.1
- Pushing the tag triggers GitHub Actions to build and publish two container tags:
ghcr.io/wikibear/meshcore-api:latestghcr.io/wikibear/meshcore-api:0.0.2
- Increment the version for every release; each new tag (e.g.
0.0.3) produces matching image tags.
Run a quick health request once the container is up:
curl -H "Authorization: Bearer $API_TOKEN" http://localhost:8000/healthThis hits the /health endpoint and proves the container accepted the token, connected to the MeshCore device, and exposed the API. You can reuse the same endpoint inside a Docker HEALTHCHECK if you want automated supervision.
GET /health,GET /status– status + queue sizesPOST /messages/channel|direct,GET/DELETE /messages/channel|directGET/POST/PUT/DELETE /channelsGET/POST/DELETE /contactsGET /settings,PUT /settings/name|position|power|frequencyGET /device/info,POST /device/reboot
- Install Python 3.11, create a venv, run
pip install -r requirements.txt - Launch locally (outside Docker) via
uvicorn app.main:app --reload - Adjust linting/tests as you integrate into your own tooling (none are bundled yet)
Distributed under GNU GPL v3.0. Contributions must remain GPL-compatible.