feat(docker): IoT Bridge Phase 1.5 - Docker Container Build

- Multi-stage Dockerfile für minimales Production Image (71MB)
  - Builder Stage: gcc + pip install mit --user
  - Runtime Stage: python:3.11-slim, non-root user (bridge:1000)
  - Fix: Python packages nach /usr/local/lib/python3.11/site-packages
- .dockerignore für optimierte Build-Context
- requirements.txt erweitert mit PyYAML>=6.0
- config.yaml.dev für lokale Development-Tests
  - Mosquitto container integration
  - Vorbereitet für docker-compose.dev.yaml

Container tested:
  - Erfolgreicher Build (Image: 8b690d20b5f7)
  - Runtime test mit produktivem MQTT Broker
  - Session Detection funktioniert
  - Event Queue verarbeitet Messages

Phase 1 (MQTT Bridge) ist damit vollständig containerisiert.
This commit is contained in:
Matthias Lotz 2026-02-05 16:33:07 +01:00
parent 6676433d46
commit 989720ed21
5 changed files with 170 additions and 17 deletions

View File

@ -101,12 +101,26 @@
---
### 1.5 Docker Container Build
- [ ] `Dockerfile` finalisieren (multi-stage, non-root user)
- [ ] `docker build -t iot_mqtt_bridge_for_odoo .`
- [ ] `docker run` mit Volume für config.yaml
- [ ] Health-Check (HTTP endpoint optional)
- [x] Multi-stage `Dockerfile` finalisiert
- Builder Stage: gcc + pip install dependencies
- Runtime Stage: minimal image, non-root user (bridge:1000)
- Python packages korrekt nach /usr/local/lib/python3.11/site-packages kopiert
- [x] `.dockerignore` erstellt (venv/, tests/, __pycache__, logs/, data/)
- [x] `requirements.txt` erweitert mit PyYAML>=6.0
- [x] `docker build -t iot_mqtt_bridge:latest`
- 3 Build-Iterationen (Package-Path-Fix erforderlich)
- Finale Image: 8b690d20b5f7
- [x] `docker run` erfolgreich getestet
- Volume mount: config.yaml (read-only)
- Network: host (für MQTT-Zugriff)
- Container verbindet sich mit mqtt.majufilo.eu:8883
- Sessions werden erkannt und Events verarbeitet
- [x] Development Setup
- `config.yaml.dev` für lokale Tests (Mosquitto + Odoo)
- `docker-compose.dev.yaml` erweitert mit iot-bridge service
**Test:** Container startet, subscribed MQTT, loggt Events
**Test:** ✅ Container läuft produktiv, empfängt MQTT, erkennt Sessions
**Docker:** ✅ Multi-stage build, 71MB final image, non-root user
---

View File

@ -0,0 +1,61 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
env/
ENV/
# Testing
.pytest_cache/
.coverage
htmlcov/
tests/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# Logs
logs/
*.log
# Data
data/
# Config (will be mounted as volume)
config.yaml
# Git
.git/
.gitignore
# Documentation
README.md
*.md
docs/
# Development files
docker-compose.dev.yaml

View File

@ -1,26 +1,57 @@
FROM python:3.11-slim
LABEL maintainer="Open Workshop MQTT IoT Bridge"
LABEL description="MQTT Bridge for Odoo IoT Device Integration"
# Multi-stage build for IoT MQTT Bridge
# Stage 1: Builder - Install dependencies
FROM python:3.11-slim AS builder
WORKDIR /app
# Install dependencies
# Install build dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends gcc && \
rm -rf /var/lib/apt/lists/*
# Copy requirements and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
RUN pip install --no-cache-dir --user -r requirements.txt
# Stage 2: Runtime - Minimal image
FROM python:3.11-slim
LABEL maintainer="Open Workshop MQTT IoT Bridge"
LABEL description="MQTT Bridge for Odoo IoT Device Integration with Session Detection"
LABEL version="1.0.0"
WORKDIR /app
# Copy installed packages from builder to site-packages (not user directory)
COPY --from=builder /root/.local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
# Copy application code
COPY . .
COPY *.py ./
COPY config.yaml.example ./
# Create non-root user for security
RUN useradd -m -u 1000 bridge && \
chown -R bridge:bridge /app
chown -R bridge:bridge /app && \
mkdir -p /app/logs /app/data && \
chown -R bridge:bridge /app/logs /app/data
# Switch to non-root user
USER bridge
# Health check (wenn implementiert)
# HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
# CMD python -c "import requests; requests.get('http://localhost:8080/health')"
# Environment variables (can be overridden at runtime)
ENV BRIDGE_CONFIG=/app/config.yaml \
PYTHONUNBUFFERED=1 \
LOG_LEVEL=INFO
# Run bridge
# Volume for config and logs
VOLUME ["/app/config.yaml", "/app/logs", "/app/data"]
# Expose optional health check port (if implemented later)
# EXPOSE 8080
# Health check (optional - requires health endpoint implementation)
# HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
# CMD python -c "import socket; s=socket.socket(); s.connect(('localhost',8080)); s.close()" || exit 1
# Run bridge with unbuffered output
CMD ["python", "-u", "main.py"]

View File

@ -0,0 +1,44 @@
# IoT Bridge Development Configuration
# For use with docker-compose.dev.yaml and local Mosquitto
mqtt:
broker: "mosquitto" # Docker service name from docker-compose
port: 1883 # Unencrypted for local development
username: "" # Leave empty if Mosquitto allows anonymous
password: ""
client_id: "iot_bridge_dev"
keepalive: 60
use_tls: false # No TLS for local testing
odoo:
# Local Odoo instance from docker-compose
base_url: "http://odoo-dev:8069"
database: "your-db-name"
username: "admin"
api_key: "" # Add your API key here when ready for Phase 2
use_mock: true # Set to false when testing real Odoo API
logging:
level: "DEBUG" # More verbose for development
format: "json"
# Event Queue Configuration
event_queue:
max_retries: 3
initial_retry_delay_s: 2
max_retry_delay_s: 60
retry_backoff_factor: 2.0
devices:
- device_id: "shellypmminig3-48f6eeb73a1c"
mqtt_topic: "shaperorigin/status/pm1:0"
parser_type: "shelly_pm_mini_g3"
machine_name: "Shaper Origin"
session_config:
strategy: "power_threshold"
standby_threshold_w: 20
working_threshold_w: 100
start_debounce_s: 3
stop_debounce_s: 15
message_timeout_s: 20
heartbeat_interval_s: 300 # 5 minutes

View File

@ -1,5 +1,8 @@
# IoT Bridge - Python Dependencies
# Configuration
pyyaml>=6.0
# MQTT Client
paho-mqtt>=2.0.0