Why Docker for IoT?
In traditional IoT projects, installing software on hundreds of edge devices is nightmare — each device has different OS version, libraries, and configuration. Docker solves this by packaging entire application with dependencies in container, ensuring runs identically everywhere.
IoT Architecture with Docker
Typical IoT system has multiple services on edge device:
┌─────────────────────────────────┐
│ Edge Device (ARM64) │
│ ┌───────────┐ ┌──────────────┐ │
│ │ MQTT │ │ Data │ │
│ │ Broker │ │ Collector │ │
│ └───────────┘ └──────────────┘ │
│ ┌───────────┐ ┌──────────────┐ │
│ │ InfluxDB │ │ Grafana │ │
│ │ (TimeSeries) │ (Dashboard) │ │
│ └───────────┘ └──────────────┘ │
└─────────────────────────────────┘
Docker Compose for Multi-Service IoT
docker-compose.yml manages entire stack:
version: "3.8"
services:
mosquitto:
image: eclipse-mosquitto:2.0
ports:
- "1883:1883"
volumes:
- ./mosquitto/config:/mosquitto/config
- mosquitto_data:/mosquitto/data
restart: unless-stopped
collector:
build: ./collector
environment:
- MQTT_HOST=mosquitto
- INFLUX_HOST=influxdb
depends_on:
- mosquitto
- influxdb
restart: unless-stopped
influxdb:
image: influxdb:2.7-alpine
volumes:
- influx_data:/var/lib/influxdb2
environment:
- DOCKER_INFLUXDB_INIT_MODE=setup
- DOCKER_INFLUXDB_INIT_USERNAME=admin
restart: unless-stopped
grafana:
image: grafana/grafana:10.2-alpine
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
restart: unless-stopped
volumes:
mosquitto_data:
influx_data:
grafana_data:
Optimize Docker for Edge Devices
1. Multi-stage Build Reduces Image Size
# Build stage
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Runtime stage
FROM python:3.11-slim
COPY --from=builder /install /usr/local
COPY . /app
WORKDIR /app
CMD ["python", "collector.py"]
Image reduces from ~900MB to ~150MB — critical when deploying over 4G network.
2. Multi-arch Build for ARM64
Many edge devices (Raspberry Pi, NVIDIA Jetson) run ARM64:
# Create buildx builder
docker buildx create --name iotbuilder --use
# Build for both AMD64 and ARM64
docker buildx build --platform linux/amd64,linux/arm64 \
-t myregistry/collector:v1.2 --push .
3. Resource Limits
Edge devices have limited RAM, always set limits:
services:
collector:
deploy:
resources:
limits:
memory: 256M
cpus: "0.5"
CI/CD for IoT Fleet
Automatic Deployment Workflow
# 1. Push code to GitHub
git push origin main
# 2. GitHub Actions builds and pushes image
# 3. On each device, Watchtower auto-updates
Use Watchtower for automatic image pulling:
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_POLL_INTERVAL=300
- WATCHTOWER_CLEANUP=true
restart: unless-stopped
Container Security for IoT
- Never run as root: use
user: "1000:1000"in compose - Read-only filesystem:
read_only: truefor containers that don't write - Limit capabilities:
security_opt: [no-new-privileges:true] - Secrets management: Docker secrets or
.envfile withchmod 600
For larger IoT fleet management, see Kubernetes for Robot Fleet with K3s and GitOps.
Monitoring and Logging
On edge devices, log rotation critical to avoid filling disk:
services:
collector:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Docker and Docker Compose let you manage IoT applications professionally — from development to production, from single device to hundreds. Combined with CI/CD and auto-updates, deploy and maintain IoT fleet without SSH to each device.