This commit is contained in:
mukowman 2026-02-19 23:07:59 +11:00 committed by GitHub
commit 1e8352a205
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 255 additions and 22 deletions

56
.github/workflows/docker-build.yml vendored Normal file
View file

@ -0,0 +1,56 @@
name: Build and Publish Docker Image
on:
push:
branches:
- main
tags:
- "v*"
pull_request:
env:
REGISTRY: ghcr.io
IMAGE_NAME: meshcore-multitcp
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Determine image tags
id: vars
shell: bash
run: |
if [[ "${GITHUB_REF}" == refs/tags/* ]]; then
TAG="${GITHUB_REF#refs/tags/}"
echo "tags=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${TAG}" >> "$GITHUB_OUTPUT"
else
echo "tags=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest" >> "$GITHUB_OUTPUT"
fi
echo "sha_tag=${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:sha-${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: |
${{ steps.vars.outputs.tags }}
${{ steps.vars.outputs.sha_tag }}

44
Dockerfile Normal file
View file

@ -0,0 +1,44 @@
FROM python:3.12-slim
# Prevents python from writing .pyc files and buffers
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1
WORKDIR /app
# System deps (kept minimal). sqlite3 CLI is optional, but handy for debugging DB files.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates sqlite3 \
&& rm -rf /var/lib/apt/lists/*
# Install python deps
# meshcore is required per README
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir meshcore
# Copy app
COPY meshcore_multitcp.py meshcore_multitcp_packets.py ./
COPY entrypoint.sh /entrypoint.sh
# Create a non-root user
RUN useradd -r -u 10001 -g users appuser \
&& chown -R appuser:users /app \
&& chmod +x /entrypoint.sh
USER appuser
# Default ports from your script
EXPOSE 5000 5001
# SQLite DB lives in /data so it can be mounted as a volume
VOLUME ["/data"]
# Default envs (override at runtime)
ENV SERVER_ADDR="0.0.0.0:5000" \
FORWARD_ADDR="0.0.0.0:5001" \
DEVICE_ADDR="192.168.5.62:5000" \
LOG_LEVEL="info" \
SQLITE="false" \
ENABLE_FORWARD="false"
ENTRYPOINT ["/entrypoint.sh"]

146
README.md
View file

@ -1,6 +1,6 @@
# meshcore_multitcp
multiplexing a mescore tcp-connected companion to multiple clients as cli-chat, observer or bots
multiplexing a meshcore tcp-connected companion to multiple clients as cli-chat, observer or bots
## what you can do with this software
@ -9,42 +9,144 @@ multiplexing a mescore tcp-connected companion to multiple clients as cli-chat,
## what you will need
- companion radio with wifi-firmware to allow tcp-connections
- linux device (tested under debian trixie)
- python3
- python meshcore package (pip install meshcore)
- linux device (tested under debian trixie) **or Docker**
- python3 (not required when using Docker)
- python meshcore package (pip install meshcore) *(not required when using Docker)*
## usage
---
## usage (native Python)
```bash
python3 meshcore_multitcp.py -d Device-IP:PORT -s Server-IP:PORT [-q|-v]
```
-d sets IP & port of your companion radio
- **-d** sets IP & port of your companion radio
- **-s** sets IP & port of the machine this script listens to clients
- **-q** minimizes CLI-output
- **-v** maximizes CLI-output
- **-f** sets secondary IP & port for listening to clients using message-storage (see S&F)
- **-sql** activates message-storage for clients which connect at second ip/port given by `-f` (see S&F)
-s sets IP & port of the machine this script listens to clients
After meshcore_multitcp is running you can connect your clients to IP/port set with `-s`.
-q minimizes CLI-output
---
-v maximizes CLI-output
## 🐳 usage (Docker)
-f sets secondary IP & port for listening to clients using message-storage (see S&F)
You can run meshcore_multitcp in a container without installing Python or dependencies.
-sql activates message-storage for clients which connect at second ip/port given by -f (see S&F)
### Build the image
From the repository root:
After meshcore_multitcp is running you can connect your clients to IP/port set with -s
```bash
docker build -t meshcore-multitcp .
```
## S&F - store & forward messages
---
Using option -sql meshcore-multitcp will store all incomming private & channel messages in local sqlite3-database.
If client connects at secondary ip/port given by -f meshcore-multitcp will forward all stored messages since last message exchange.
Dumping large number of messages can cause hung up clients and messages could be lost.
### Run — basic mode
WARNING: Actually theres no database-clean-up - so if you connect a new client first time, meshcore-multitcp will try to forward all known messages.
Starts the proxy listening on port **5000** and connects to your companion radio.
```bash
docker run -d \
--name meshcore-multitcp \
-p 5000:5000 \
-e SERVER_ADDR="0.0.0.0:5000" \
-e DEVICE_ADDR="192.168.5.62:5000" \
meshcore-multitcp
```
Replace `192.168.5.62:5000` with your device IP and port.
Clients can then connect to:
```
<host-ip>:5000
```
---
### Run — Store & Forward (SQLite enabled)
Enables message storage and a secondary forwarding port.
```bash
docker run -d \
--name meshcore-multitcp \
-p 5000:5000 \
-p 5001:5001 \
-e SERVER_ADDR="0.0.0.0:5000" \
-e DEVICE_ADDR="192.168.5.62:5000" \
-e ENABLE_FORWARD="true" \
-e FORWARD_ADDR="0.0.0.0:5001" \
-e SQLITE="true" \
-v meshcore_data:/data \
meshcore-multitcp
```
---
### Logging options (Docker)
| LOG_LEVEL | Behaviour |
|-----------|-----------|
| `info` (default) | Standard output |
| `quiet` | Minimal logging |
| `debug` | Verbose logging |
Example:
```bash
-e LOG_LEVEL="debug"
```
---
### Environment variables (Docker)
| Variable | Required | Description |
|----------|----------|-------------|
| `SERVER_ADDR` | Yes | IP:PORT for clients to connect |
| `DEVICE_ADDR` | Yes | IP:PORT of companion radio |
| `ENABLE_FORWARD` | No | Enable secondary listener |
| `FORWARD_ADDR` | No | IP:PORT for store-forward clients |
| `SQLITE` | No | Enable message storage |
| `LOG_LEVEL` | No | `info`, `quiet`, or `debug` |
---
### Stop / remove container
```bash
docker stop meshcore-multitcp
docker rm meshcore-multitcp
```
---
## S&F — store & forward messages
Using option `-sql` (or `SQLITE=true` in Docker) meshcore-multitcp will store all incoming private & channel messages in a local sqlite3 database.
If a client connects at the secondary IP/port given by `-f` (or `FORWARD_ADDR` in Docker), meshcore-multitcp will forward all stored messages since the last message exchange.
Dumping a large number of messages can cause hung clients and messages could be lost.
⚠️ WARNING: There is currently no database clean-up.
If a new client connects for the first time, meshcore-multitcp will attempt to forward all stored messages.
---
## what you should know before you start
This software comes as it is without any guarantee to work stable and secure.
It contains modified parts of the original meshcore_py-scripts.
There are several things untested und a lot of bugs in it.
Some client-app functions doesn't work as expected and could throw timeout-errors or crash the whole app.
This software comes as it is without any guarantee to work stable and secure.
It contains modified parts of the original meshcore_py-scripts.
There are several things untested and a lot of bugs in it.
Some client-app functions don't work as expected and could throw timeout errors or crash the whole app.
TEST
---
## TEST

31
entrypoint.sh Normal file
View file

@ -0,0 +1,31 @@
#!/bin/sh
set -eu
ARGS=""
# Required args (-s and -d)
ARGS="$ARGS -s ${SERVER_ADDR}"
ARGS="$ARGS -d ${DEVICE_ADDR}"
# Optional forwarding listener (-f) and sqlite (-sql)
if [ "${ENABLE_FORWARD}" = "true" ]; then
ARGS="$ARGS -f ${FORWARD_ADDR}"
fi
if [ "${SQLITE}" = "true" ]; then
# Put DB in mounted volume; your script uses sqlite_file = 'meshcore_multitcp.db'
# so we run from /data to keep it persistent.
cd /data
ARGS="$ARGS -sql"
else
cd /app
fi
# Logging controls (-q or -v). Default is info (no flag).
if [ "${LOG_LEVEL}" = "quiet" ]; then
ARGS="$ARGS -q"
elif [ "${LOG_LEVEL}" = "debug" ]; then
ARGS="$ARGS -v"
fi
exec python3 /app/meshcore_multitcp.py $ARGS