mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-04-25 00:35:38 +00:00
- Updated docker-compose.yml to clarify device access instructions for Linux and added notes for ARM devices regarding network mode. - Enhanced docker-setup.sh to resolve symlinks for serial devices, improving Docker compatibility and providing fallback options for device paths.
321 lines
13 KiB
Bash
Executable File
321 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
# Setup script for Docker deployment
|
|
# Creates necessary directories and copies example config
|
|
|
|
set -e
|
|
|
|
echo "Setting up meshcore-bot Docker environment..."
|
|
|
|
# Create data directories
|
|
echo "Creating data directories..."
|
|
mkdir -p data/{config,databases,logs,backups}
|
|
|
|
# Copy example config if config doesn't exist
|
|
if [ ! -f "data/config/config.ini" ]; then
|
|
if [ -f "config.ini.example" ]; then
|
|
echo "Copying config.ini.example to data/config/config.ini..."
|
|
cp config.ini.example data/config/config.ini
|
|
else
|
|
echo "⚠️ Warning: config.ini.example not found. Please create data/config/config.ini manually."
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "✓ Config file already exists at data/config/config.ini"
|
|
fi
|
|
|
|
# Detect platform
|
|
PLATFORM=$(uname -s)
|
|
CONFIG_FILE="data/config/config.ini"
|
|
|
|
# Function to update config.ini using sed (works with both existing and new configs)
|
|
update_config() {
|
|
local section=$1
|
|
local key=$2
|
|
local value=$3
|
|
|
|
# Check if section exists
|
|
if ! grep -q "^\[$section\]" "$CONFIG_FILE"; then
|
|
echo "" >> "$CONFIG_FILE"
|
|
echo "[$section]" >> "$CONFIG_FILE"
|
|
fi
|
|
|
|
# Check if key exists in section (look for key= with optional spaces)
|
|
if grep -q "^$key[[:space:]]*=" "$CONFIG_FILE"; then
|
|
# Update existing key (use | as delimiter to avoid issues with / in paths)
|
|
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
sed -i '' "s|^$key[[:space:]]*=.*|$key = $value|" "$CONFIG_FILE"
|
|
else
|
|
sed -i "s|^$key[[:space:]]*=.*|$key = $value|" "$CONFIG_FILE"
|
|
fi
|
|
else
|
|
# Add new key after section header
|
|
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
sed -i '' "/^\[$section\]/a\\
|
|
$key = $value
|
|
" "$CONFIG_FILE"
|
|
else
|
|
sed -i "/^\[$section\]/a $key = $value" "$CONFIG_FILE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Update database and log paths for Docker
|
|
echo ""
|
|
echo "Updating config.ini for Docker paths..."
|
|
|
|
UPDATED_COUNT=0
|
|
|
|
# Update Bot database path
|
|
update_config "Bot" "db_path" "/data/databases/meshcore_bot.db"
|
|
echo " ✓ Updated [Bot] db_path"
|
|
((UPDATED_COUNT++))
|
|
|
|
# Update Logging file path
|
|
update_config "Logging" "log_file" "/data/logs/meshcore_bot.log"
|
|
echo " ✓ Updated [Logging] log_file"
|
|
((UPDATED_COUNT++))
|
|
|
|
# Update Web_Viewer database path (if section exists)
|
|
if grep -q "^\[Web_Viewer\]" "$CONFIG_FILE"; then
|
|
update_config "Web_Viewer" "db_path" "/data/databases/bot_data.db"
|
|
echo " ✓ Updated [Web_Viewer] db_path"
|
|
((UPDATED_COUNT++))
|
|
fi
|
|
|
|
# Update PacketCapture paths (if section exists)
|
|
if grep -q "^\[PacketCapture\]" "$CONFIG_FILE"; then
|
|
# Only update output_file if it's set to a relative path
|
|
CURRENT_OUTPUT=$(grep "^output_file[[:space:]]*=" "$CONFIG_FILE" 2>/dev/null | sed 's/^output_file[[:space:]]*=[[:space:]]*//' | tr -d ' ' || echo "")
|
|
if [ -n "$CURRENT_OUTPUT" ] && [[ ! "$CURRENT_OUTPUT" == /* ]]; then
|
|
# Relative path - update to logs directory
|
|
update_config "PacketCapture" "output_file" "/data/logs/packets.jsonl"
|
|
echo " ✓ Updated [PacketCapture] output_file"
|
|
((UPDATED_COUNT++))
|
|
fi
|
|
|
|
# Update private_key_path if it's a relative path
|
|
CURRENT_KEY=$(grep "^private_key_path[[:space:]]*=" "$CONFIG_FILE" 2>/dev/null | sed 's/^private_key_path[[:space:]]*=[[:space:]]*//' | tr -d ' ' || echo "")
|
|
if [ -n "$CURRENT_KEY" ] && [[ ! "$CURRENT_KEY" == /* ]]; then
|
|
# Relative path - update to config directory (read-only is fine for keys)
|
|
update_config "PacketCapture" "private_key_path" "/data/config/private_key"
|
|
echo " ✓ Updated [PacketCapture] private_key_path"
|
|
((UPDATED_COUNT++))
|
|
fi
|
|
fi
|
|
|
|
# Update MapUploader private_key_path (if section exists)
|
|
if grep -q "^\[MapUploader\]" "$CONFIG_FILE"; then
|
|
CURRENT_KEY=$(grep "^private_key_path[[:space:]]*=" "$CONFIG_FILE" 2>/dev/null | sed 's/^private_key_path[[:space:]]*=[[:space:]]*//' | tr -d ' ' || echo "")
|
|
if [ -n "$CURRENT_KEY" ] && [[ ! "$CURRENT_KEY" == /* ]]; then
|
|
# Relative path - update to config directory
|
|
update_config "MapUploader" "private_key_path" "/data/config/private_key"
|
|
echo " ✓ Updated [MapUploader] private_key_path"
|
|
((UPDATED_COUNT++))
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo "✓ Updated $UPDATED_COUNT path(s) for Docker deployment"
|
|
|
|
# Try to detect serial device
|
|
echo ""
|
|
echo "Detecting serial devices..."
|
|
|
|
SERIAL_DEVICE=""
|
|
DOCKER_DEVICE_PATH=""
|
|
|
|
if [[ "$PLATFORM" == "Linux" ]]; then
|
|
# Linux: Prefer /dev/serial/by-id/ for stable device identification
|
|
if [ -d "/dev/serial/by-id" ] && [ -n "$(ls -A /dev/serial/by-id 2>/dev/null)" ]; then
|
|
# Look for common MeshCore device patterns (case-insensitive)
|
|
# Prioritize devices that might be MeshCore-related
|
|
DEVICE=$(ls /dev/serial/by-id/* 2>/dev/null | grep -iE "(meshcore|heltec|rak|ch340|cp210|ft232)" | head -1)
|
|
# If no specific match, take the first USB serial device
|
|
if [ -z "$DEVICE" ]; then
|
|
DEVICE=$(ls /dev/serial/by-id/* 2>/dev/null | grep -i "usb" | head -1)
|
|
fi
|
|
# Last resort: any serial device
|
|
if [ -z "$DEVICE" ]; then
|
|
DEVICE=$(ls /dev/serial/by-id/* 2>/dev/null | head -1)
|
|
fi
|
|
|
|
if [ -n "$DEVICE" ] && [ -e "$DEVICE" ]; then
|
|
SERIAL_DEVICE="$DEVICE"
|
|
# For Docker, we'll map to /dev/ttyUSB0 in container
|
|
DOCKER_DEVICE_PATH="/dev/ttyUSB0"
|
|
echo "✓ Found serial device (by-id): $SERIAL_DEVICE"
|
|
fi
|
|
fi
|
|
|
|
# Fallback to /dev/ttyUSB* or /dev/ttyACM* if by-id not found
|
|
if [ -z "$SERIAL_DEVICE" ]; then
|
|
# Try ttyUSB first (more common)
|
|
for dev in /dev/ttyUSB* /dev/ttyACM*; do
|
|
if [ -e "$dev" ]; then
|
|
SERIAL_DEVICE="$dev"
|
|
DOCKER_DEVICE_PATH="/dev/ttyUSB0"
|
|
echo "✓ Found serial device: $SERIAL_DEVICE"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Update docker-compose.yml if device found (Linux only)
|
|
if [ -n "$SERIAL_DEVICE" ] && [ -f "docker-compose.yml" ]; then
|
|
echo "Updating docker-compose.yml with device mapping..."
|
|
|
|
# Check if devices section exists (commented or uncommented)
|
|
if grep -qE "^ #? devices:" docker-compose.yml; then
|
|
# Uncomment and update existing devices section
|
|
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
# Uncomment devices line
|
|
sed -i '' 's/^ # devices:/ devices:/' docker-compose.yml
|
|
# Update device path - find commented device line and replace
|
|
sed -i '' "s|^ # - /dev/.*| - $SERIAL_DEVICE:$DOCKER_DEVICE_PATH|" docker-compose.yml
|
|
# Also handle if already uncommented
|
|
sed -i '' "s|^ - /dev/.*| - $SERIAL_DEVICE:$DOCKER_DEVICE_PATH|" docker-compose.yml
|
|
else
|
|
# Uncomment devices line
|
|
sed -i 's/^ # devices:/ devices:/' docker-compose.yml
|
|
# Update device path - find commented device line and replace
|
|
sed -i "s|^ # - /dev/.*| - $SERIAL_DEVICE:$DOCKER_DEVICE_PATH|" docker-compose.yml
|
|
# Also handle if already uncommented
|
|
sed -i "s|^ - /dev/.*| - $SERIAL_DEVICE:$DOCKER_DEVICE_PATH|" docker-compose.yml
|
|
fi
|
|
else
|
|
# Add devices section after restart line
|
|
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
sed -i '' "/^ restart: unless-stopped/a\\
|
|
\\
|
|
# Device access for serial ports (Linux)\\
|
|
devices:\\
|
|
- $SERIAL_DEVICE:$DOCKER_DEVICE_PATH
|
|
" docker-compose.yml
|
|
else
|
|
sed -i "/^ restart: unless-stopped/a\\
|
|
\\
|
|
# Device access for serial ports (Linux)\\
|
|
devices:\\
|
|
- $SERIAL_DEVICE:$DOCKER_DEVICE_PATH
|
|
" docker-compose.yml
|
|
fi
|
|
fi
|
|
echo "✓ Updated docker-compose.yml with device: $SERIAL_DEVICE -> $DOCKER_DEVICE_PATH"
|
|
fi
|
|
|
|
elif [[ "$PLATFORM" == "Darwin" ]]; then
|
|
# macOS: Use /dev/cu.* devices
|
|
DEVICE=$(ls /dev/cu.usbmodem* /dev/cu.usbserial* 2>/dev/null | head -1)
|
|
if [ -n "$DEVICE" ]; then
|
|
SERIAL_DEVICE="$DEVICE"
|
|
echo "✓ Found serial device: $SERIAL_DEVICE"
|
|
echo " Note: Docker Desktop on macOS doesn't support device passthrough."
|
|
echo " Consider using TCP connection or running natively on macOS."
|
|
fi
|
|
fi
|
|
|
|
# Update config.ini with serial device if found
|
|
if [ -n "$SERIAL_DEVICE" ]; then
|
|
if [[ "$PLATFORM" == "Linux" ]] && [[ "$SERIAL_DEVICE" == /dev/serial/by-id/* ]]; then
|
|
# On Linux with by-id path, resolve to actual device for Docker compatibility
|
|
# Docker containers may not resolve symlinks correctly, so use the actual device
|
|
ACTUAL_DEVICE=$(readlink -f "$SERIAL_DEVICE" 2>/dev/null || echo "")
|
|
if [ -n "$ACTUAL_DEVICE" ] && [ -e "$ACTUAL_DEVICE" ]; then
|
|
# Use actual device path for better Docker compatibility
|
|
update_config "Connection" "serial_port" "$ACTUAL_DEVICE"
|
|
echo "✓ Updated config.ini with serial port: $ACTUAL_DEVICE"
|
|
echo " (resolved from $SERIAL_DEVICE)"
|
|
else
|
|
# Fallback to by-id path if resolution fails
|
|
update_config "Connection" "serial_port" "$SERIAL_DEVICE"
|
|
echo "✓ Updated config.ini with serial port: $SERIAL_DEVICE"
|
|
echo " ⚠️ Note: If Docker can't access this symlink, use the actual device path"
|
|
fi
|
|
elif [[ "$PLATFORM" == "Linux" ]]; then
|
|
# On Linux, use the device path directly
|
|
update_config "Connection" "serial_port" "$SERIAL_DEVICE"
|
|
echo "✓ Updated config.ini with serial port: $SERIAL_DEVICE"
|
|
else
|
|
# macOS: just note it, but user needs to handle differently
|
|
update_config "Connection" "serial_port" "$SERIAL_DEVICE"
|
|
echo "✓ Updated config.ini with serial port: $SERIAL_DEVICE"
|
|
echo " ⚠️ Remember: Docker Desktop on macOS can't access serial devices directly."
|
|
fi
|
|
else
|
|
echo "⚠️ No serial device detected. You may need to:"
|
|
echo " - Connect your MeshCore device"
|
|
echo " - Manually set serial_port in config.ini"
|
|
echo " - Or use TCP/BLE connection instead"
|
|
fi
|
|
|
|
# Detect git branch and set Docker image tag
|
|
echo ""
|
|
echo "Detecting git branch for Docker image tag..."
|
|
|
|
# Try to get current branch name
|
|
GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
|
|
DOCKER_IMAGE_TAG="latest"
|
|
DOCKER_IMAGE_REGISTRY="ghcr.io/agessaman/meshcore-bot"
|
|
|
|
if [ -n "$GIT_BRANCH" ]; then
|
|
# Map branch names to image tags
|
|
case "$GIT_BRANCH" in
|
|
main|master)
|
|
DOCKER_IMAGE_TAG="latest"
|
|
;;
|
|
*)
|
|
# Use branch name as tag (e.g., dev -> dev, feature/xyz -> feature-xyz)
|
|
DOCKER_IMAGE_TAG=$(echo "$GIT_BRANCH" | sed 's/[\/_]/-/g')
|
|
;;
|
|
esac
|
|
echo " ✓ Detected branch: $GIT_BRANCH -> image tag: $DOCKER_IMAGE_TAG"
|
|
else
|
|
echo " ⚠️ Not a git repository or branch detection failed, using 'latest'"
|
|
fi
|
|
|
|
# Create or update .env file for docker-compose
|
|
ENV_FILE=".env"
|
|
if [ ! -f "$ENV_FILE" ] || ! grep -q "^DOCKER_IMAGE_TAG=" "$ENV_FILE" 2>/dev/null; then
|
|
echo "" >> "$ENV_FILE"
|
|
echo "# Docker image configuration (auto-generated by docker-setup.sh)" >> "$ENV_FILE"
|
|
echo "DOCKER_IMAGE_REGISTRY=$DOCKER_IMAGE_REGISTRY" >> "$ENV_FILE"
|
|
echo "DOCKER_IMAGE_TAG=$DOCKER_IMAGE_TAG" >> "$ENV_FILE"
|
|
echo " ✓ Created/updated .env file with image tag: $DOCKER_IMAGE_TAG"
|
|
else
|
|
# Update existing .env file
|
|
if [[ "$PLATFORM" == "Darwin" ]]; then
|
|
sed -i '' "s|^DOCKER_IMAGE_TAG=.*|DOCKER_IMAGE_TAG=$DOCKER_IMAGE_TAG|" "$ENV_FILE"
|
|
sed -i '' "s|^DOCKER_IMAGE_REGISTRY=.*|DOCKER_IMAGE_REGISTRY=$DOCKER_IMAGE_REGISTRY|" "$ENV_FILE"
|
|
else
|
|
sed -i "s|^DOCKER_IMAGE_TAG=.*|DOCKER_IMAGE_TAG=$DOCKER_IMAGE_TAG|" "$ENV_FILE"
|
|
sed -i "s|^DOCKER_IMAGE_REGISTRY=.*|DOCKER_IMAGE_REGISTRY=$DOCKER_IMAGE_REGISTRY|" "$ENV_FILE"
|
|
fi
|
|
echo " ✓ Updated .env file with image tag: $DOCKER_IMAGE_TAG"
|
|
fi
|
|
|
|
# Set permissions (container runs as UID 1000)
|
|
echo ""
|
|
echo "Setting permissions..."
|
|
chmod -R 755 data/
|
|
chown -R 1000:1000 data/ 2>/dev/null || echo "Note: Could not set ownership (may need sudo)"
|
|
|
|
echo ""
|
|
echo "✓ Setup complete!"
|
|
echo ""
|
|
echo "Next steps:"
|
|
if [ -z "$SERIAL_DEVICE" ]; then
|
|
echo "1. Connect your MeshCore device or configure TCP/BLE connection"
|
|
fi
|
|
echo "1. Review data/config/config.ini and adjust settings if needed"
|
|
echo "2. Build the Docker image (to avoid pull warnings):"
|
|
echo " docker compose build"
|
|
echo ""
|
|
echo "3. Start the container:"
|
|
echo " docker compose up -d"
|
|
echo ""
|
|
echo " Or build and start in one command:"
|
|
echo " docker compose up -d --build"
|
|
echo ""
|
|
echo "4. View logs:"
|
|
echo " docker compose logs -f"
|