Split Docker Compose into base/dev/prod/traefik overrides with multi-instance support

- Split docker-compose.yml into base config + environment overrides
  - docker-compose.dev.yml: port mappings for local development
  - docker-compose.prod.yml: external proxy-net network, no exposed ports
  - docker-compose.traefik.yml: optional Traefik auto-discovery labels
- Parameterize container and volume names with COMPOSE_PROJECT_NAME
  - Default: hub-dev (containers: hub-dev-api, volumes: hub-dev_hub_data)
  - Override per instance for multi-instance deployments (hub-prod, hub-beta)
- Add Makefile with build/up/down/logs/backup/restore targets
- Add TRAEFIK_DOMAIN env var for Traefik routing configuration
- Update UPGRADING.md with volume migration instructions (rename + copy methods)
- Update README.md with multi-instance deployment and backup/restore sections
This commit is contained in:
Louis King
2026-04-14 20:41:26 +01:00
parent 123dc180f0
commit f4648d7fe7
10 changed files with 440 additions and 66 deletions
+11
View File
@@ -29,6 +29,17 @@
# =============================================================================
# These settings apply to all services
# Docker Compose project name
# Used as a prefix for container names (e.g., hub-dev-api) and volume names
# (e.g., hub-dev_hub_data). Change per instance when running multiple deployments
# on the same Docker host (e.g., hub-prod, hub-beta, hub-stg).
# For multi-instance setups, see the "Multi-Instance Deployment" section in README.md.
COMPOSE_PROJECT_NAME=hub-dev
# Domain name for this instance (only needed for Traefik deployments)
# Used by docker-compose.traefik.yml to configure routing rules
# TRAEFIK_DOMAIN=meshcore.example.com
# Docker image version tag to use
# Options: latest, main, v1.0.0, etc.
IMAGE_VERSION=latest
+1
View File
@@ -3,6 +3,7 @@
!example/data/
/seed/
!example/seed/
/backup/
/content/
# Byte-compiled / optimized / DLL files
+7 -2
View File
@@ -324,7 +324,11 @@ meshcore-hub/
│ └── collector/ # Collector data
│ └── meshcore.db # SQLite database
├── Dockerfile # Docker build configuration
── docker-compose.yml # Docker Compose services
── docker-compose.yml # Docker Compose base config
├── docker-compose.dev.yml # Development overrides (port mappings)
├── docker-compose.prod.yml # Production overrides (proxy network)
├── docker-compose.traefik.yml # Optional Traefik labels
└── SCHEMAS.md
```
## MQTT Topic Structure
@@ -585,6 +589,7 @@ meshcore-hub collector
See [PLAN.md](PLAN.md#configuration-environment-variables) for complete list.
Key variables:
- `COMPOSE_PROJECT_NAME` - Docker Compose project prefix for containers and volumes (default: `hub-dev`)
- `DATA_HOME` - Base directory for runtime data (default: `./data`)
- `SEED_HOME` - Directory containing seed data files (default: `./seed`)
- `CONTENT_HOME` - Directory containing custom content (pages, media) (default: `./content`)
@@ -663,7 +668,7 @@ The database can be seeded with node tags and network members from YAML files in
meshcore-hub collector seed
# With Docker Compose
docker compose --profile seed up
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile seed up
```
**Note:** Once the admin UI is enabled (`WEB_ADMIN_ENABLED=true`), tags should be managed through the web interface rather than seed files.
+40
View File
@@ -0,0 +1,40 @@
ifneq (,$(wildcard ./.env))
include .env
export
endif
PROFILES ?= mqtt core
COMPOSE_FILES = -f docker-compose.yml -f docker-compose.dev.yml
VOLUMES = $(COMPOSE_PROJECT_NAME)_hub_data $(COMPOSE_PROJECT_NAME)_mqtt_broker_data \
$(COMPOSE_PROJECT_NAME)_prometheus_data $(COMPOSE_PROJECT_NAME)_alertmanager_data \
$(COMPOSE_PROJECT_NAME)_packetcapture_data
.PHONY: build up down logs backup restore
build:
docker compose $(COMPOSE_FILES) --profile all build --no-cache
up:
docker compose $(COMPOSE_FILES) $(foreach p,$(PROFILES),--profile $(p)) up -d --force-recreate
down:
docker compose $(COMPOSE_FILES) --profile all down --remove-orphans
logs:
docker compose $(COMPOSE_FILES) --profile all logs -f
backup:
@mkdir -p backup
@for vol in $(VOLUMES); do \
echo "Backing up $$vol..."; \
docker run --rm -v $$vol:/data -v $(PWD)/backup:/backup \
alpine tar czf /backup/$$vol-$$(date +%Y%m%d-%H%M%S).tar.gz -C / data; \
done
@echo "Backups saved to $(PWD)/backup/"
restore:
@if [ -z "$(FILE)" ]; then echo "Usage: make restore FILE=backup/<tarball>"; exit 1; fi
@vol=$$(basename $(FILE) | sed 's/-[0-9]\{8\}-[0-9]\{6\}\.tar\.gz//'); \
echo "Restoring $$vol from $(FILE)..."; \
docker run --rm -v $$vol:/data -v $(PWD)/backup:/backup \
alpine sh -c "cd / && tar xzf /backup/$$(basename $(FILE))"
+124 -14
View File
@@ -82,12 +82,13 @@ The quickest way to get started is running the entire stack on a single machine
**Steps:**
```bash
# Create a directory, download the Docker Compose file and
# Create a directory, download the Docker Compose files and
# example environment configuration file
mkdir meshcore-hub
cd meshcore-hub
wget https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/refs/heads/main/docker-compose.yml
wget https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/refs/heads/main/docker-compose.dev.yml
wget https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/refs/heads/main/.env.example
# Copy and configure environment
@@ -95,7 +96,7 @@ cp .env.example .env
# Edit .env: set MQTT_HOST to your MQTT broker if not using the local one
# Start the entire stack with local MQTT broker
docker compose --profile mqtt --profile core up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile mqtt --profile core up -d
# View the web dashboard
open http://localhost:8080
@@ -107,7 +108,29 @@ This starts all services: MQTT broker, collector, API, and web dashboard. MeshCo
### Docker Compose Profiles
Docker Compose uses **profiles** to select which services to run:
Docker Compose uses **profiles** to select which services to run. The configuration is split across multiple files:
| File | Purpose |
|------|---------|
| `docker-compose.yml` | Base shared config (services, profiles, healthchecks, environment) |
| `docker-compose.dev.yml` | Development overrides (port mappings for direct access) |
| `docker-compose.prod.yml` | Production overrides (external proxy network, no exposed ports) |
| `docker-compose.traefik.yml` | Optional Traefik auto-discovery labels |
All `docker compose` commands require explicit file selection with `-f`:
```bash
# Development (default — exposes ports for local access)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Production (generic reverse proxy — nginx, caddy, etc.)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Production (Traefik)
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.traefik.yml up -d
```
Service profiles:
| Profile | Services | Use Case |
|---------|----------|----------|
@@ -123,27 +146,112 @@ Docker Compose uses **profiles** to select which services to run:
```bash
# Create database schema
docker compose --profile migrate run --rm db-migrate
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile migrate run --rm db-migrate
# Seed the database
docker compose --profile seed run --rm seed
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile seed run --rm seed
# Start core services with local MQTT broker
docker compose --profile mqtt --profile core up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile mqtt --profile core up -d
# Or connect to external MQTT (configure MQTT_HOST in .env)
docker compose --profile core up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile core up -d
# Start everything including packet capture observer
docker compose --profile mqtt --profile core --profile receiver up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile mqtt --profile core --profile receiver up -d
# View logs
docker compose logs -f
docker compose -f docker-compose.yml -f docker-compose.dev.yml logs -f
# Stop services
docker compose down
docker compose -f docker-compose.yml -f docker-compose.dev.yml down
```
### Multi-Instance Deployment
Multiple MeshCore Hub instances can run on the same Docker host (e.g., production, beta, staging). Each instance uses a unique `COMPOSE_PROJECT_NAME` to isolate containers, volumes, and networking.
**1. Create a shared proxy network** (once):
```bash
docker network create proxy-net
```
**2. Set up each instance in its own directory:**
```bash
# Production instance
mkdir hub-prod && cd hub-prod
cp ../docker-compose.yml ../docker-compose.prod.yml ../.env.example .
cp .env.example .env
# Edit .env: set COMPOSE_PROJECT_NAME=hub-prod
```
```bash
# Beta instance
mkdir hub-beta && cd hub-beta
cp ../docker-compose.yml ../docker-compose.prod.yml ../.env.example .
cp .env.example .env
# Edit .env: set COMPOSE_PROJECT_NAME=hub-beta
```
**3. Configure your reverse proxy** to route traffic to the container names:
| Instance | API Container | Web Container |
|----------|--------------|---------------|
| Production | `hub-prod-api:8000` | `hub-prod-web:8080` |
| Beta | `hub-beta-api:8000` | `hub-beta-web:8080` |
**4. Start each instance:**
```bash
# Production (generic reverse proxy)
docker compose -f docker-compose.yml -f docker-compose.prod.yml --profile core up -d
# Beta (with Traefik)
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.traefik.yml --profile core up -d
```
Containers and volumes are automatically prefixed with the project name — no compose file edits needed per instance.
### Backup & Restore
#### Using Makefile
```bash
# Back up all volumes to backup/
make backup
# Restore a specific volume
make restore FILE=backup/hub-dev_hub_data-20260414-120000.tar.gz
```
#### Using shell commands
```bash
# Back up all volumes
source .env 2>/dev/null || true
mkdir -p backup
for vol in ${COMPOSE_PROJECT_NAME:-hub-dev}_hub_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_mqtt_broker_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_prometheus_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_alertmanager_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_packetcapture_data; do
echo "Backing up $vol..."
docker run --rm -v $vol:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/$vol-$(date +%Y%m%d-%H%M%S).tar.gz -C / data
done
# Restore a specific volume (volume name derived from tarball filename)
source .env 2>/dev/null || true
FILE=backup/${COMPOSE_PROJECT_NAME:-hub-dev}_hub_data-20260414-120000.tar.gz
vol=$(basename "$FILE" | sed 's/-[0-9]\{8\}-[0-9]\{6\}\.tar\.gz//')
docker run --rm -v $vol:/data -v $(pwd)/backup:/backup \
alpine sh -c "cd / && tar xzf /backup/$(basename $FILE)"
```
> **Note:** Replace `hub-dev` with your `COMPOSE_PROJECT_NAME` if using a different instance name.
### Manual Installation
```bash
@@ -417,8 +525,7 @@ The markdown content is rendered as-is, so include your own `# Heading` if desir
Pages automatically appear in the navigation menu and sitemap. With Docker, mount the content directory:
```yaml
# docker-compose.yml (already configured)
volumes:
# docker-compose.yml (already configured)volumes:
- ${CONTENT_HOME:-./content}:/content:ro
environment:
- CONTENT_HOME=/content
@@ -433,7 +540,7 @@ The database can be seeded with node tags and network members from YAML files in
Seeding is a separate process and must be run explicitly:
```bash
docker compose --profile seed up
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile seed up
```
This imports data from the following files (if they exist):
@@ -646,7 +753,10 @@ meshcore-hub/
│ └── images/ # Custom images (logo.svg/png/jpg/jpeg/webp replace default logo)
├── data/ # Runtime data directory (DATA_HOME, created at runtime)
├── Dockerfile # Docker build configuration
├── docker-compose.yml # Docker Compose services
├── docker-compose.yml # Docker Compose base config
├── docker-compose.dev.yml # Development overrides (port mappings)
├── docker-compose.prod.yml # Production overrides (proxy network)
├── docker-compose.traefik.yml # Optional Traefik labels
├── SCHEMAS.md # Event schema documentation
├── UPGRADING.md # Upgrade guide for breaking changes
└── AGENTS.md # AI assistant guidelines
+153 -26
View File
@@ -16,29 +16,39 @@ This guide covers upgrading from a previous MeshCore Hub release to the current
| DB table | `event_receivers` | `event_observers` |
| API commands | `/api/v1/commands/*` | Removed |
| Compose profiles | `receiver`, `sender`, `mock` | `receiver` (packet-capture) |
| Compose files | Single `docker-compose.yml` | Base + environment overrides (`.dev.yml`, `.prod.yml`) |
| Container names | `meshcore-*` | Parameterized via `COMPOSE_PROJECT_NAME` (default: `hub-dev-*`) |
| Volume names | `meshcore_*` | Parameterized via `COMPOSE_PROJECT_NAME` (default: `hub-dev_*`) |
## Step 1: Backup the Database
## Step 1: Backup
**Do not skip this step.** The database migration renames columns and tables, and while it has been tested, you should always have a backup.
**Do not skip this step.** Back up all data volumes before proceeding.
### Using Makefile
```bash
# Create a timestamped backup of the database volume
docker run --rm \
-v meshcore_hub_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/meshcore-hub-db-$(date +%Y%m%d-%H%M%S).tar.gz -C / data
make backup
```
# Verify the backup was created
ls -lh meshcore-hub-db-*.tar.gz
### Using shell commands
```bash
source .env 2>/dev/null || true
mkdir -p backup
for vol in ${COMPOSE_PROJECT_NAME:-hub-dev}_hub_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_mqtt_broker_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_prometheus_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_alertmanager_data \
${COMPOSE_PROJECT_NAME:-hub-dev}_packetcapture_data; do
docker run --rm -v $vol:/data -v $(pwd)/backup:/backup \
alpine tar czf /backup/$vol-$(date +%Y%m%d-%H%M%S).tar.gz -C / data
done
```
To restore from backup if needed:
```bash
docker run --rm \
-v meshcore_hub_data:/data \
-v $(pwd):/backup \
alpine sh -c "cd / && tar xzf /backup/meshcore-hub-db-YYYYMMDD-HHMMSS.tar.gz"
make restore FILE=backup/hub-dev_hub_data-YYYYMMDD-HHMMSS.tar.gz
```
## Step 2: Stop and Remove Containers
@@ -51,21 +61,109 @@ docker compose down --remove-orphans
> **Important:** Do NOT use `--volumes` / `-v`. That would delete your database. The `--remove-orphans` flag cleans up old services (like `interface-receiver`, `interface-sender`) that no longer exist in the new compose file.
## Step 3: Update Configuration Files
## Step 3: Rename Docker Volumes
Container and volume names are now parameterized via `COMPOSE_PROJECT_NAME`. The default is `hub-dev`, so volumes are renamed from `meshcore_*` to `hub-dev_*`.
First, check which volumes you have:
```bash
docker volume ls | grep meshcore
```
### Volumes to migrate
These volumes always need migrating:
| Old Name | New Name |
|----------|----------|
| `meshcore_hub_data` | `hub-dev_hub_data` |
| `meshcore_prometheus_data` | `hub-dev_prometheus_data` |
| `meshcore_alertmanager_data` | `hub-dev_alertmanager_data` |
| `meshcore_packetcapture_data` | `hub-dev_packetcapture_data` |
For the MQTT broker, it depends on your current version:
| Your Current Broker | Volume to Migrate | Action |
|---------------------|-------------------|--------|
| `meshcore-mqtt-broker` | `meshcore_mqtt_broker_data``hub-dev_mqtt_broker_data` | Rename or copy below |
| Mosquitto (older) | `meshcore_mosquitto_data`, `meshcore_mosquitto_log` | **Remove** — no longer used. New volume created automatically on first run. |
### Option A: Rename (Docker Engine 23.0+)
> **Note:** `docker volume rename` is not available in all Docker builds (e.g., Docker Desktop). If the command is not found, use Option B instead.
```bash
docker volume rename meshcore_hub_data hub-dev_hub_data
docker volume rename meshcore_prometheus_data hub-dev_prometheus_data
docker volume rename meshcore_alertmanager_data hub-dev_alertmanager_data
docker volume rename meshcore_packetcapture_data hub-dev_packetcapture_data
# Only if you already have meshcore-mqtt-broker (skip if still on Mosquitto)
docker volume rename meshcore_mqtt_broker_data hub-dev_mqtt_broker_data
```
### Option B: Copy (all Docker versions)
If `docker volume rename` is not available in your Docker build:
```bash
# For each volume: create new, copy data, remove old
docker volume create hub-dev_hub_data
docker run --rm -v meshcore_hub_data:/from -v hub-dev_hub_data:/to alpine sh -c "cp -a /from/. /to/"
docker volume create hub-dev_prometheus_data
docker run --rm -v meshcore_prometheus_data:/from -v hub-dev_prometheus_data:/to alpine sh -c "cp -a /from/. /to/"
docker volume create hub-dev_alertmanager_data
docker run --rm -v meshcore_alertmanager_data:/from -v hub-dev_alertmanager_data:/to alpine sh -c "cp -a /from/. /to/"
docker volume create hub-dev_packetcapture_data
docker run --rm -v meshcore_packetcapture_data:/from -v hub-dev_packetcapture_data:/to alpine sh -c "cp -a /from/. /to/"
# Only if you already have meshcore-mqtt-broker (skip if still on Mosquitto)
docker volume create hub-dev_mqtt_broker_data
docker run --rm -v meshcore_mqtt_broker_data:/from -v hub-dev_mqtt_broker_data:/to alpine sh -c "cp -a /from/. /to/"
# Verify the new volumes have data, then remove old ones
docker volume rm meshcore_hub_data meshcore_prometheus_data meshcore_alertmanager_data meshcore_packetcapture_data
# Only if you already have meshcore-mqtt-broker
docker volume rm meshcore_mqtt_broker_data
```
### Clean up old Mosquitto volumes (if applicable)
If upgrading from the Mosquitto era, remove the unused volumes:
```bash
# Skip if these don't exist
docker volume rm meshcore_mosquitto_data meshcore_mosquitto_log
```
> **Note:** If any volumes show "in use", remove any stopped containers first: `docker rm -f <container_id>`.
> **Note:** If setting up a multi-instance deployment (e.g., `hub-prod`, `hub-beta`), use that project name instead of `hub-dev`.
> **Note:** After migrating volumes, you may see warnings like `volume "hub-dev_hub_data" already exists but was not created by Docker Compose. Use \`external: true\` to use an existing volume`. This is safe to ignore — it appears because the volumes were created manually during migration rather than by Docker Compose. Fresh deployments will not see this warning.
## Step 4: Update Configuration Files
Download the latest configuration files:
```bash
# Download the new docker-compose.yml
# Download the base compose file and environment overrides
wget -O docker-compose.yml https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/docker-compose.yml
wget -O docker-compose.dev.yml https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/docker-compose.dev.yml
wget -O docker-compose.prod.yml https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/docker-compose.prod.yml
# Download the new .env.example for reference
wget -O .env.example https://raw.githubusercontent.com/ipnet-mesh/meshcore-hub/main/.env.example
```
Then compare your existing `.env` against the new `.env.example` and update it (see Step 4).
Then compare your existing `.env` against the new `.env.example` and update it (see Step 5).
## Step 4: Migrate Your `.env` File
## Step 5: Migrate Your `.env` File
### Variables to Remove
@@ -110,6 +208,9 @@ MQTT_WS_PORT=9001
### Variables to Add
```bash
# Docker Compose project name (container and volume prefix)
COMPOSE_PROJECT_NAME=hub-dev
# MQTT subscriber authentication for the collector
# The collector connects as a subscriber to read all published topics
# including /internal. Set these to match your broker's SUBSCRIBER_1 config.
@@ -131,47 +232,47 @@ PACKETCAPTURE_IATA=LOC
All other `PACKETCAPTURE_*` variables have sensible defaults in `docker-compose.yml` and only need to be set in `.env` if you want to override them. See `.env.example` for the full list.
## Step 5: Run Database Migration
## Step 6: Run Database Migration
The migration renames `receiver_node_id``observer_node_id` across all event tables and `event_receivers``event_observers`:
```bash
docker compose --profile core run --rm db-migrate
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile core run --rm db-migrate
```
This runs automatically as part of the `core` profile, but can also be run standalone with the `migrate` profile:
```bash
docker compose --profile migrate run --rm db-migrate
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile migrate run --rm db-migrate
```
## Step 6: Start Services
## Step 7: Start Services
### With local MQTT broker (single-host deployment)
```bash
# Start everything including the MQTT broker
docker compose --profile mqtt --profile core up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile mqtt --profile core up -d
# Or include packet capture on the same host
docker compose --profile mqtt --profile core --profile receiver up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile mqtt --profile core --profile receiver up -d
```
### With external MQTT broker
```bash
# Start core services only (broker runs elsewhere)
docker compose --profile core up -d
docker compose -f docker-compose.yml -f docker-compose.dev.yml --profile core up -d
```
### Verify
```bash
# Check all containers are running
docker compose ps
docker compose -f docker-compose.yml -f docker-compose.dev.yml ps
# Check collector connected to MQTT
docker compose logs collector | grep -i "connected to mqtt"
docker compose -f docker-compose.yml -f docker-compose.dev.yml logs collector | grep -i "connected to mqtt"
# Check the web dashboard
open http://localhost:8080
@@ -235,6 +336,32 @@ The following Docker Compose services have been removed:
The `packet-capture` service uses the [meshcore-packet-capture](https://github.com/agessaman/meshcore-packet-capture) image and is included in `docker-compose.yml` under the `receiver` profile for an easy transition.
### New Docker Compose File Structure
The Docker Compose configuration is now split into multiple files:
| File | Purpose |
|------|---------|
| `docker-compose.yml` | Base shared config (services, profiles, healthchecks, environment) |
| `docker-compose.dev.yml` | Development overrides (port mappings for direct access) |
| `docker-compose.prod.yml` | Production overrides (external proxy network, no exposed ports) |
| `docker-compose.traefik.yml` | Optional Traefik auto-discovery labels |
All `docker compose` commands now require explicit file selection:
```bash
# Development (exposes ports for local access)
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# Production (connects to reverse proxy network)
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# Production with Traefik
docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.traefik.yml up -d
```
Container and volume names are parameterized via `COMPOSE_PROJECT_NAME` in `.env`. This enables multiple instances (e.g., `hub-prod`, `hub-beta`) on the same Docker host.
### Removed API Endpoints
The command dispatch API endpoints have been removed:
+28
View File
@@ -0,0 +1,28 @@
# MeshCore Hub - Development Docker Compose Override
#
# Exposes service ports for local development and testing.
# NOT intended for production use — use docker-compose.prod.yml instead.
#
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
services:
mqtt:
ports:
- "${MQTT_PORT:-1883}:${MQTT_PORT:-1883}"
api:
ports:
- "${API_PORT:-8000}:8000"
web:
ports:
- "${WEB_PORT:-8080}:8080"
prometheus:
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
alertmanager:
ports:
- "${ALERTMANAGER_PORT:-9093}:9093"
+29
View File
@@ -0,0 +1,29 @@
# MeshCore Hub - Production Docker Compose Override
#
# Connects api and web services to an external proxy network for
# reverse proxy access (Traefik, Nginx, Caddy, etc.).
# No ports are exposed directly — all traffic goes through the reverse proxy.
#
# Prerequisites:
# docker network create proxy-net
#
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
#
# With Traefik:
# docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.traefik.yml up -d
services:
api:
networks:
- default
- proxy-net
web:
networks:
- default
- proxy-net
networks:
proxy-net:
external: true
+33
View File
@@ -0,0 +1,33 @@
# MeshCore Hub - Traefik Docker Compose Override
#
# Adds Traefik auto-discovery labels to api and web services.
# Requires docker-compose.prod.yml (for the proxy-net network).
#
# Set DOMAIN in your .env file to the hostname for this instance.
#
# Prerequisites:
# - Traefik configured with Docker provider and attached to proxy-net
# - TRAEFIK_DOMAIN set in .env (e.g., TRAEFIK_DOMAIN=meshcore.example.com)
#
# Usage:
# docker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.traefik.yml up -d
services:
api:
labels:
- "traefik.enable=true"
- "traefik.http.services.${COMPOSE_PROJECT_NAME:-hub-dev}-api.loadbalancer.server.port=8000"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-api.rule=Host(`${TRAEFIK_DOMAIN}`) && (PathPrefix(`/api`) || PathPrefix(`/metrics`) || PathPrefix(`/health`))"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-api.entrypoints=websecure"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-api.tls=true"
- "traefik.docker.network=proxy-net"
web:
labels:
- "traefik.enable=true"
- "traefik.http.services.${COMPOSE_PROJECT_NAME:-hub-dev}-web.loadbalancer.server.port=8080"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-web.rule=Host(`${TRAEFIK_DOMAIN}`)"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-web.entrypoints=websecure"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-web.tls=true"
- "traefik.http.routers.${COMPOSE_PROJECT_NAME:-hub-dev}-web.priority=1"
- "traefik.docker.network=proxy-net"
+14 -24
View File
@@ -7,13 +7,11 @@ services:
# ==========================================================================
mqtt:
image: ghcr.io/ipnet-mesh/meshcore-mqtt-broker:latest
container_name: meshcore-mqtt
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-mqtt
profiles:
- all
- mqtt
restart: unless-stopped
ports:
- "${MQTT_PORT:-1883}:${MQTT_PORT:-1883}"
volumes:
- mqtt_broker_data:/data
environment:
@@ -64,7 +62,7 @@ services:
# ==========================================================================
packet-capture:
image: ghcr.io/agessaman/meshcore-packet-capture:${PACKETCAPTURE_IMAGE_VERSION:-latest}
container_name: meshcore-packet-capture
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-packet-capture
profiles:
- all
- receiver
@@ -136,7 +134,7 @@ services:
build:
context: .
dockerfile: Dockerfile
container_name: meshcore-collector
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-collector
profiles:
- all
- core
@@ -196,7 +194,7 @@ services:
build:
context: .
dockerfile: Dockerfile
container_name: meshcore-api
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-api
profiles:
- all
- core
@@ -206,8 +204,6 @@ services:
condition: service_completed_successfully
collector:
condition: service_started
ports:
- "${API_PORT:-8000}:8000"
volumes:
- hub_data:/data
environment:
@@ -249,7 +245,7 @@ services:
build:
context: .
dockerfile: Dockerfile
container_name: meshcore-web
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-web
profiles:
- all
- core
@@ -257,8 +253,6 @@ services:
depends_on:
api:
condition: service_healthy
ports:
- "${WEB_PORT:-8080}:8080"
volumes:
- ${CONTENT_HOME:-./content}:/content:ro
environment:
@@ -315,7 +309,7 @@ services:
build:
context: .
dockerfile: Dockerfile
container_name: meshcore-db-migrate
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-db-migrate
profiles:
- all
- core
@@ -338,7 +332,7 @@ services:
build:
context: .
dockerfile: Dockerfile
container_name: meshcore-seed
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-seed
profiles:
- seed
restart: "no"
@@ -357,7 +351,7 @@ services:
# ==========================================================================
prometheus:
image: prom/prometheus:latest
container_name: meshcore-prometheus
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-prometheus
profiles:
- all
- metrics
@@ -365,8 +359,6 @@ services:
depends_on:
api:
condition: service_healthy
ports:
- "${PROMETHEUS_PORT:-9090}:9090"
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=30d"
@@ -380,13 +372,11 @@ services:
# ==========================================================================
alertmanager:
image: prom/alertmanager:latest
container_name: meshcore-alertmanager
container_name: ${COMPOSE_PROJECT_NAME:-hub-dev}-alertmanager
profiles:
- all
- metrics
restart: unless-stopped
ports:
- "${ALERTMANAGER_PORT:-9093}:9093"
volumes:
- ./etc/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
- alertmanager_data:/alertmanager
@@ -399,12 +389,12 @@ services:
# ==========================================================================
volumes:
hub_data:
name: meshcore_hub_data
name: ${COMPOSE_PROJECT_NAME:-hub-dev}_hub_data
mqtt_broker_data:
name: meshcore_mqtt_broker_data
name: ${COMPOSE_PROJECT_NAME:-hub-dev}_mqtt_broker_data
prometheus_data:
name: meshcore_prometheus_data
name: ${COMPOSE_PROJECT_NAME:-hub-dev}_prometheus_data
alertmanager_data:
name: meshcore_alertmanager_data
name: ${COMPOSE_PROJECT_NAME:-hub-dev}_alertmanager_data
packetcapture_data:
name: meshcore_packetcapture_data
name: ${COMPOSE_PROJECT_NAME:-hub-dev}_packetcapture_data