mirror of
https://github.com/ajvpot/meshexplorer.git
synced 2026-08-10 10:32:43 +02:00
release-prep: unified docker-compose + .env.example
Single root compose brings up the whole stack on one internal network: clickhouse (healthchecked) -> migrate (one-shot) -> meshcoreingest + meshexplorer, with the discord-bot behind a "bot" profile. Web app/bot connect as the readonly ClickHouse user; ingest/migrate use the default user. Named volume replaces the host /tank path. .env.example documents every variable with placeholders; root .gitignore keeps real .env out of git. Drops the per-project compose files. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# MeshExplorer unified stack configuration.
|
||||
# Copy this file to .env and fill in the values, then run:
|
||||
# docker compose up --build
|
||||
# (add `--profile bot` to also start the Discord relay).
|
||||
|
||||
# ─── ClickHouse ──────────────────────────────────────────────────────────────
|
||||
# The read/write "default" user is used by the ingest daemon and the migration
|
||||
# runner. Set a real password before deploying.
|
||||
CLICKHOUSE_DB=default
|
||||
CLICKHOUSE_USER=default
|
||||
CLICKHOUSE_PASSWORD=changeme
|
||||
|
||||
# Read-only user used by the web app and the Discord bot. This account is only
|
||||
# reachable on the internal docker network; the default matches ingest/clickhouse/users.xml.
|
||||
CLICKHOUSE_READONLY_USER=readonly
|
||||
CLICKHOUSE_READONLY_PASSWORD=readonly
|
||||
|
||||
# ─── MeshCore MQTT ingest ────────────────────────────────────────────────────
|
||||
# JSON array of MQTT brokers to subscribe to for meshcore packets. Each entry:
|
||||
# { "url": "...", "username": "...", "password": "...", "topics": ["meshcore/#"] }
|
||||
# "topics" is optional and defaults to ["meshcore/#"]. The ingest daemon exits
|
||||
# with an error if this is empty, so configure at least one broker.
|
||||
MQTT_BROKERS=[{"url":"tcp://mqtt.example.com:1883","username":"CHANGE_ME","password":"CHANGE_ME","topics":["meshcore/#"]}]
|
||||
MQTT_CLIENT_ID=meshcore-ingest
|
||||
|
||||
# ─── Web app ─────────────────────────────────────────────────────────────────
|
||||
# Base URL for client-side API calls. Leave empty to use relative URLs.
|
||||
NEXT_PUBLIC_API_URL=
|
||||
|
||||
# ─── Discord relay bot (optional, --profile bot) ─────────────────────────────
|
||||
# Required when running the bot. Create a webhook in your Discord server.
|
||||
DISCORD_WEBHOOK_URL=
|
||||
# Optional: post into a specific thread instead of the channel.
|
||||
DISCORD_THREAD_ID=
|
||||
# Region filter for messages (e.g. seattle).
|
||||
MESH_REGION=seattle
|
||||
# Poll interval (ms) and batch size.
|
||||
POLL_INTERVAL=300
|
||||
MAX_ROWS_PER_POLL=50
|
||||
# Comma-separated base64 private keys used to decrypt channel messages.
|
||||
PRIVATE_KEYS=
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# Local environment configuration (never commit real secrets)
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
|
||||
# Go build artifacts from the ingest module
|
||||
/ingest/meshcoreingest
|
||||
/ingest/migrate
|
||||
/ingest/clickhouse-meshingest
|
||||
*.test
|
||||
*.out
|
||||
@@ -0,0 +1,134 @@
|
||||
services:
|
||||
# ClickHouse database (custom image bundles the meshcore decrypt UDF)
|
||||
clickhouse:
|
||||
build: ./ingest/clickhouse
|
||||
environment:
|
||||
- CLICKHOUSE_DB=${CLICKHOUSE_DB:-default}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-default}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-}
|
||||
- CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1
|
||||
ports:
|
||||
# Published to localhost only, for debugging. Not required by the stack.
|
||||
- "127.0.0.1:8123:8123"
|
||||
- "127.0.0.1:9000:9000"
|
||||
volumes:
|
||||
- clickhouse-data:/var/lib/clickhouse
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "clickhouse-client --user $$CLICKHOUSE_USER --password $$CLICKHOUSE_PASSWORD --query 'SELECT 1' || exit 1"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 30
|
||||
start_period: 10s
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- meshnet
|
||||
|
||||
# One-shot migration runner (goose). Applies the meshcore schema then exits.
|
||||
migrate:
|
||||
build: ./ingest
|
||||
command:
|
||||
- "./migrate"
|
||||
- "-host"
|
||||
- "clickhouse"
|
||||
- "-port"
|
||||
- "9000"
|
||||
- "-database"
|
||||
- "${CLICKHOUSE_DB:-default}"
|
||||
- "-username"
|
||||
- "${CLICKHOUSE_USER:-default}"
|
||||
- "-password"
|
||||
- "${CLICKHOUSE_PASSWORD:-}"
|
||||
- "-path"
|
||||
- "migrations"
|
||||
- "-action"
|
||||
- "up"
|
||||
depends_on:
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
restart: "no"
|
||||
networks:
|
||||
- meshnet
|
||||
|
||||
# MeshCore MQTT -> ClickHouse ingest daemon
|
||||
meshcoreingest:
|
||||
build: ./ingest
|
||||
command: ["./meshcoreingest"]
|
||||
environment:
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=9000
|
||||
- CLICKHOUSE_DB=${CLICKHOUSE_DB:-default}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-default}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-}
|
||||
- MQTT_BROKERS=${MQTT_BROKERS}
|
||||
- MQTT_CLIENT_ID=${MQTT_CLIENT_ID:-meshcore-ingest}
|
||||
depends_on:
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- meshnet
|
||||
|
||||
# MeshExplorer web app (Next.js). Reads ClickHouse over HTTP (8123) as the
|
||||
# readonly user.
|
||||
meshexplorer:
|
||||
build:
|
||||
context: ./meshexplorer
|
||||
dockerfile: Dockerfile
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- PORT=3000
|
||||
- HOSTNAME=0.0.0.0
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=8123
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_READONLY_USER:-readonly}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_READONLY_PASSWORD:-readonly}
|
||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-}
|
||||
ports:
|
||||
- "3001:3000"
|
||||
depends_on:
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
networks:
|
||||
- meshnet
|
||||
|
||||
# MeshCore -> Discord relay bot. Optional: enabled with the "bot" profile.
|
||||
# docker compose --profile bot up
|
||||
discord-bot:
|
||||
build:
|
||||
context: ./meshexplorer
|
||||
dockerfile: Dockerfile.bot
|
||||
profiles: ["bot"]
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- CLICKHOUSE_HOST=clickhouse
|
||||
- CLICKHOUSE_PORT=8123
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_READONLY_USER:-readonly}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_READONLY_PASSWORD:-readonly}
|
||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||
- DISCORD_THREAD_ID=${DISCORD_THREAD_ID:-}
|
||||
- MESH_REGION=${MESH_REGION:-seattle}
|
||||
- POLL_INTERVAL=${POLL_INTERVAL:-300}
|
||||
- MAX_ROWS_PER_POLL=${MAX_ROWS_PER_POLL:-50}
|
||||
- PRIVATE_KEYS=${PRIVATE_KEYS:-}
|
||||
depends_on:
|
||||
clickhouse:
|
||||
condition: service_healthy
|
||||
migrate:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
networks:
|
||||
- meshnet
|
||||
|
||||
volumes:
|
||||
clickhouse-data:
|
||||
|
||||
networks:
|
||||
meshnet:
|
||||
driver: bridge
|
||||
@@ -1,59 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
meshexplorer:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "3001:3000"
|
||||
environment:
|
||||
# Next.js Configuration
|
||||
- NODE_ENV=production
|
||||
- PORT=3000
|
||||
- HOSTNAME=0.0.0.0
|
||||
|
||||
# ClickHouse Database Configuration
|
||||
- CLICKHOUSE_HOST=${CLICKHOUSE_HOST:-clickhouse}
|
||||
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT:-8123}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-default}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
|
||||
|
||||
# Next.js API Configuration
|
||||
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-}
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
networks:
|
||||
- shared-network
|
||||
|
||||
discord-bot:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.bot
|
||||
environment:
|
||||
# Node.js Configuration
|
||||
- NODE_ENV=production
|
||||
|
||||
# ClickHouse Database Configuration
|
||||
- CLICKHOUSE_HOST=${CLICKHOUSE_HOST:-clickhouse}
|
||||
- CLICKHOUSE_PORT=${CLICKHOUSE_PORT:-8123}
|
||||
- CLICKHOUSE_USER=${CLICKHOUSE_USER:-default}
|
||||
- CLICKHOUSE_PASSWORD=${CLICKHOUSE_PASSWORD:-password}
|
||||
|
||||
# Discord Bot Configuration
|
||||
- DISCORD_WEBHOOK_URL=${DISCORD_WEBHOOK_URL}
|
||||
- DISCORD_THREAD_ID=${DISCORD_THREAD_ID:-}
|
||||
- MESH_REGION=${MESH_REGION:-seattle}
|
||||
- POLL_INTERVAL=${POLL_INTERVAL:-1000}
|
||||
- MAX_ROWS_PER_POLL=${MAX_ROWS_PER_POLL:-50}
|
||||
- PRIVATE_KEYS=${PRIVATE_KEYS:-}
|
||||
restart: unless-stopped
|
||||
init: true
|
||||
networks:
|
||||
- shared-network
|
||||
depends_on:
|
||||
- meshexplorer
|
||||
|
||||
networks:
|
||||
shared-network:
|
||||
external: true
|
||||
Reference in New Issue
Block a user