mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-03-30 12:05:38 +00:00
- Modified docker-compose.yml to support using a pre-built image from GitHub Container Registry, with automatic tagging based on the current git branch. - Enhanced docker-setup.sh to detect the current git branch and set the Docker image tag accordingly, creating or updating the .env file with the appropriate configuration.
310 lines
12 KiB
Bash
Executable File
310 lines
12 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, use it directly in config (more stable)
|
|
update_config "Connection" "serial_port" "$SERIAL_DEVICE"
|
|
echo "✓ Updated config.ini with serial port: $SERIAL_DEVICE"
|
|
elif [[ "$PLATFORM" == "Linux" ]]; then
|
|
# On Linux, use the Docker mapped path in config
|
|
update_config "Connection" "serial_port" "$DOCKER_DEVICE_PATH"
|
|
echo "✓ Updated config.ini with serial port: $DOCKER_DEVICE_PATH (mapped from $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"
|