Files
potato-mesh/docker-compose.yml
T

220 lines
6.9 KiB
YAML

# Copyright © 2025-26 l5yth & contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
x-web-base: &web-base
image: ghcr.io/l5yth/potato-mesh-web-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:${POTATOMESH_IMAGE_TAG:-latest}
environment:
APP_ENV: ${APP_ENV:-production}
RACK_ENV: ${RACK_ENV:-production}
SITE_NAME: ${SITE_NAME:-PotatoMesh Demo}
# Canonical names win; CHANNEL/FREQUENCY stay for existing .env files.
MESHTASTIC_PRESET: ${MESHTASTIC_PRESET:-}
MESHTASTIC_FREQ: ${MESHTASTIC_FREQ:-}
CHANNEL: ${CHANNEL:-#LongFast}
FREQUENCY: ${FREQUENCY:-915MHz}
MESHCORE_PRESET: ${MESHCORE_PRESET:-}
MESHCORE_FREQ: ${MESHCORE_FREQ:-}
RETICULUM_PRESET: ${RETICULUM_PRESET:-}
RETICULUM_FREQ: ${RETICULUM_FREQ:-}
MAP_CENTER: ${MAP_CENTER:-38.761944,-27.090833}
MAP_ZOOM: ${MAP_ZOOM:-}
MAX_DISTANCE: ${MAX_DISTANCE:-42}
CONTACT_LINK: ${CONTACT_LINK:-#potatomesh:dod.ngo}
FEDERATION: ${FEDERATION:-1}
PRIVATE: ${PRIVATE:-0}
API_TOKEN: ${API_TOKEN}
INSTANCE_DOMAIN: ${INSTANCE_DOMAIN}
DEBUG: ${DEBUG:-0}
ANNOUNCEMENT: ${ANNOUNCEMENT:-}
EVENTS: ${EVENTS:-1}
OG_IMAGE_URL: ${OG_IMAGE_URL:-}
OG_IMAGE_NO_SANDBOX: ${OG_IMAGE_NO_SANDBOX:-1}
PAGES_DIR: ${PAGES_DIR:-/app/pages}
PROM_REPORT_IDS: ${PROM_REPORT_IDS:-}
command: ["ruby", "app.rb", "-p", "41447", "-o", "0.0.0.0"]
volumes:
- potatomesh_data:/app/.local/share/potato-mesh
- potatomesh_config:/app/.config/potato-mesh
- potatomesh_logs:/app/logs
- potatomesh_pages:/app/pages
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
x-ingestor-base: &ingestor-base
image: ghcr.io/l5yth/potato-mesh-ingestor-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:${POTATOMESH_IMAGE_TAG:-latest}
environment:
CONNECTION: ${CONNECTION:-/dev/ttyACM0}
CHANNEL_INDEX: ${CHANNEL_INDEX:-0}
ALLOWED_CHANNELS: ${ALLOWED_CHANNELS:-}
HIDDEN_CHANNELS: ${HIDDEN_CHANNELS:-}
DROP_VIA_MQTT: ${DROP_VIA_MQTT:-0}
API_TOKEN: ${API_TOKEN}
INSTANCE_DOMAIN: ${INSTANCE_DOMAIN:-http://web:41447}
DEBUG: ${DEBUG:-0}
PROTOCOL: ${PROTOCOL:-meshtastic}
# PROTOCOL=reticulum only. On bare metal this defaults to ~/.reticulum, the
# stack rnsd already uses; a container has no such stack, so it points at
# the volume that persists instead.
RETICULUM_CONFIG_DIR: ${RETICULUM_CONFIG_DIR:-/app/.config/potato-mesh/reticulum}
# Unset ingests RNode interfaces only; set * to ingest every interface.
# Keep the default bare, not `""`: Compose substitutes it as literal text.
RETICULUM_INTERFACES: ${RETICULUM_INTERFACES:-}
# Read from the RNS config when unset; these only override it.
RETICULUM_FREQ: ${RETICULUM_FREQ:-}
RETICULUM_PRESET: ${RETICULUM_PRESET:-}
# Required for TRANSPORT=udp, and for PROTOCOL=reticulum: with the
# potatomesh_reticulum volume nothing announces, so without it the heartbeat
# never registers and the protocol's packets/hour stays at zero.
INGESTOR_NODE_ID: ${INGESTOR_NODE_ID:-}
ENERGY_SAVING: ${ENERGY_SAVING:-0}
MESHCORE_SELF_TELEMETRY_SECONDS: ${MESHCORE_SELF_TELEMETRY_SECONDS:-3600}
MESHCORE_TELEMETRY_POLL_SECONDS: ${MESHCORE_TELEMETRY_POLL_SECONDS:-300}
MESHCORE_TELEMETRY_POLL_24H_EXEMPT: ${MESHCORE_TELEMETRY_POLL_24H_EXEMPT:-}
# TRANSPORT=udp needs host networking; see "Passive UDP transport" in README.
TRANSPORT: ${TRANSPORT:-api}
PRIMARY_CHANNEL_ONLY: ${PRIMARY_CHANNEL_ONLY:-}
PRIMARY_CHANNEL_KEY: ${PRIMARY_CHANNEL_KEY:-}
PRIMARY_CHANNEL_NAME: ${PRIMARY_CHANNEL_NAME:-}
MESH_UDP_GROUP: ${MESH_UDP_GROUP:-}
MESH_UDP_PORT: ${MESH_UDP_PORT:-}
MESH_UDP_ALLOWED_SOURCES: ${MESH_UDP_ALLOWED_SOURCES:-}
TX_ENABLED: ${TX_ENABLED:-0}
TX_ANNOUNCE: ${TX_ANNOUNCE:-0}
FEDERATION: ${FEDERATION:-1}
PRIVATE: ${PRIVATE:-0}
volumes:
- potatomesh_data:/app/.local/share/potato-mesh
- potatomesh_config:/app/.config/potato-mesh
# The RNS stack's own config/identity (PROTOCOL=reticulum). Deliberately a
# separate volume nested inside the shared config mount: potatomesh_config
# is initialised by the web image, whose user is pinned to uid 1000, while
# this image's user is not — so RNS could not create its directory there.
- potatomesh_reticulum:/app/.config/potato-mesh/reticulum
- potatomesh_logs:/app/logs
- /dev:/dev
device_cgroup_rules:
- 'c 166:* rwm' # ttyACM devices
- 'c 188:* rwm' # ttyUSB devices
- 'c 4:* rwm' # ttyS devices
privileged: false
restart: unless-stopped
deploy:
resources:
limits:
memory: 256M
cpus: '0.25'
reservations:
memory: 128M
cpus: '0.1'
x-matrix-bridge-base: &matrix-bridge-base
image: ghcr.io/l5yth/potato-mesh-matrix-bridge-${POTATOMESH_IMAGE_ARCH:-linux-amd64}:${POTATOMESH_IMAGE_TAG:-latest}
volumes:
- potatomesh_matrix_bridge_state:/app
- type: bind
source: ./matrix/Config.toml
target: /app/Config.toml
read_only: true
bind:
create_host_path: false
restart: unless-stopped
deploy:
resources:
limits:
memory: 128M
cpus: '0.1'
reservations:
memory: 64M
cpus: '0.05'
services:
web:
<<: *web-base
network_mode: host
ingestor:
<<: *ingestor-base
network_mode: host
depends_on:
- web
extra_hosts:
- "web:127.0.0.1"
web-bridge:
<<: *web-base
container_name: potatomesh-web-bridge
networks:
- potatomesh-network
ports:
- "41447:41447"
profiles:
- bridge
ingestor-bridge:
<<: *ingestor-base
container_name: potatomesh-ingestor-bridge
networks:
- potatomesh-network
depends_on:
- web-bridge
profiles:
- bridge
matrix-bridge:
<<: *matrix-bridge-base
network_mode: host
profiles:
- matrix
depends_on:
- web
extra_hosts:
- "web:127.0.0.1"
matrix-bridge-bridge:
<<: *matrix-bridge-base
container_name: potatomesh-matrix-bridge
networks:
- potatomesh-network
depends_on:
- web-bridge
ports:
- "41448:41448"
profiles:
- bridge
volumes:
potatomesh_reticulum:
driver: local
potatomesh_data:
driver: local
potatomesh_config:
driver: local
potatomesh_logs:
driver: local
potatomesh_pages:
driver: local
potatomesh_matrix_bridge_state:
driver: local
networks:
potatomesh-network:
driver: bridge