From 973f0030e40f0f7e2c9d1616a398dd980ab5dcd6 Mon Sep 17 00:00:00 2001 From: mukowman Date: Thu, 19 Feb 2026 18:21:51 +1100 Subject: [PATCH 1/5] Add Dockerfile for Python application setup --- Dockerfile | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..aced1a3 --- /dev/null +++ b/Dockerfile @@ -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"] From 3f99f1740980c1097632c9f9b7d6c5d2335f9d65 Mon Sep 17 00:00:00 2001 From: mukowman Date: Thu, 19 Feb 2026 18:22:22 +1100 Subject: [PATCH 2/5] Create entrypoint.sh for application startup Add entrypoint script to configure and run the application. --- entrypoint.sh | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 entrypoint.sh diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..a6481e4 --- /dev/null +++ b/entrypoint.sh @@ -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 From 5f6f1d92f9d42871a2b02e9f21a7194884d1c94d Mon Sep 17 00:00:00 2001 From: mukowman Date: Thu, 19 Feb 2026 18:36:40 +1100 Subject: [PATCH 3/5] Add GitHub Actions workflow for Docker image build --- .github/workflows/docker-build.yml | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/docker-build.yml diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..39bd3e5 --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,47 @@ +name: Build and Publish Docker Image + +on: + push: + branches: [ "main" ] + tags: [ "v*" ] + pull_request: + +env: + IMAGE_NAME: meshcore-multitcp + +jobs: + build: + runs-on: ubuntu-latest + + permissions: + contents: read + packages: write + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ghcr.io/${{ github.repository_owner }}/meshcore-multitcp + tags: | + type=ref,event=branch + type=ref,event=tag + type=sha + type=raw,value=latest,enable={{is_default_branch}} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tag From 90139ed95ba7909df78d4b2b4427e08f81069d80 Mon Sep 17 00:00:00 2001 From: mukowman Date: Thu, 19 Feb 2026 18:37:43 +1100 Subject: [PATCH 4/5] Update Docker build workflow for improved tagging --- .github/workflows/docker-build.yml | 45 ++++++++++++++++++------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 39bd3e5..e8da11a 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -2,11 +2,14 @@ name: Build and Publish Docker Image on: push: - branches: [ "main" ] - tags: [ "v*" ] + branches: + - main + tags: + - "v*" pull_request: env: + REGISTRY: ghcr.io IMAGE_NAME: meshcore-multitcp jobs: @@ -18,30 +21,36 @@ jobs: packages: write steps: - - name: Checkout repo + - name: Checkout uses: actions/checkout@v4 - - name: Log in to GitHub Container Registry + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR uses: docker/login-action@v3 with: - registry: ghcr.io + registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Extract metadata (tags, labels) - id: meta - uses: docker/metadata-action@v5 - with: - images: ghcr.io/${{ github.repository_owner }}/meshcore-multitcp - tags: | - type=ref,event=branch - type=ref,event=tag - type=sha - type=raw,value=latest,enable={{is_default_branch}} + - 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 Docker image - uses: docker/build-push-action@v5 + - name: Build and push + uses: docker/build-push-action@v6 with: context: . push: true - tags: ${{ steps.meta.outputs.tag + tags: | + ${{ steps.vars.outputs.tags }} + ${{ steps.vars.outputs.sha_tag }} From 327427955878252525e844fdbe8c533f14985c47 Mon Sep 17 00:00:00 2001 From: mukowman Date: Thu, 19 Feb 2026 22:11:53 +1100 Subject: [PATCH 5/5] Revise README for improved instructions and details Updated README to enhance clarity and add Docker usage instructions. --- README.md | 146 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 124 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index bc9e539..d9dd8d2 100644 --- a/README.md +++ b/README.md @@ -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: + +``` +: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 \ No newline at end of file +--- + +## TEST