Docker 在嵌入式设备中的常用玩法目录基础概念交叉编译环境固件构建与打包CI/CD 流水线设备端容器化运行模拟与测试常用工具与镜像实战示例注意事项与最佳实践1. 基础概念什么是嵌入式 Docker在嵌入式开发中Docker 主要用于环境隔离为不同项目/芯片维护独立的编译环境可复现构建确保团队成员使用完全一致的工具链CI/CD 集成在服务器上自动化构建嵌入式固件设备端部署在资源受限的设备上运行容器化应用Docker 多架构支持# 注册 QEMU 模拟器关键步骤用于构建 ARM 镜像dockerrun--rm--privilegedmultiarch/qemu-user-static--reset-pyes# 验证dockerrun--rmarm64v8/ubuntuuname-m# 输出: aarch642. 交叉编译环境2.1 统一工具链容器最常见的用法——把交叉编译工具链封装成 Docker 镜像# Dockerfile.arm-gcc FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ gcc-arm-none-eabi \ gdb-multiarch \ make \ cmake \ ninja-build \ python3 \ python3-pip \ rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /workspace # 默认进入 bash CMD [/bin/bash]使用方式# 构建镜像dockerbuild-tarm-gcc-fDockerfile.arm-gcc.# 挂载项目目录并编译dockerrun--rm-v$(pwd):/workspace arm-gcc\makeCROSS_COMPILEarm-none-eabi- all2.2 多工具链切换# Dockerfile.multi-toolchain FROM ubuntu:22.04 # ARM Cortex-M (STM32, NRF52 等) RUN apt-get update apt-get install -y gcc-arm-none-eabi # ARM Cortex-A (Linux 应用) RUN apt-get install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu # RISC-V RUN apt-get install -y gcc-riscv64-unknown-elf # MIPS RUN apt-get install -y gcc-mips-linux-gnu RUN rm -rf /var/lib/apt/lists/* WORKDIR /workspace2.3 Yocto / Buildroot 环境# Dockerfile.yocto FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ gawk wget git diffstat unzip texinfo gcc build-essential \ chrpath socat cpio python3 python3-pip python3-pexpect \ python3-git python3-jinja2 python3-subunit \ xz-utils debianutils iputils-ping \ libsdl1.2-dev xterm \ locales \ rm -rf /var/lib/apt/lists/* RUN locale-gen en_US.UTF-8 ENV LANGen_US.UTF-8 RUN useradd -m builder USER builder WORKDIR /home/builder # 克隆 Yocto RUN git clone -b kirkstone \ https://git.yoctoproject.org/poky.git /home/builder/poky3. 固件构建与打包3.1 可复现固件构建# Dockerfile.firmware-build FROM ubuntu:22.04 # 固定版本的工具链 RUN apt-get update apt-get install -y \ gcc-arm-none-eabi15:10.3-2021.10-* \ make cmake \ rm -rf /var/lib/apt/lists/* # 固定版本的构建脚本 COPY build.sh /opt/build.sh RUN chmod x /opt/build.sh WORKDIR /firmware ENTRYPOINT [/opt/build.sh]# 构建固件dockerrun--rm-v$(pwd):/firmware firmware-build:v1.0# 产出物自动落在当前目录ls-labuild/*.bin3.2 OpenWrt 构建# Dockerfile.openwrt FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ build-essential ccache ecj fastjar file g gawk \ gettext git java-propose-class-default libelf-dev \ libncurses5-dev libncursesw5-dev libssl-dev \ python3 python2.7-dev python3-distutils python3-setuptools \ rsync subversion swig time unzip wget xsltproc zlib1g-dev \ rm -rf /var/lib/apt/lists/* RUN git clone https://github.com/openwrt/openwrt.git /opt/openwrt WORKDIR /opt/openwrt RUN ./scripts/feeds update -a ./scripts/feeds install -a4. CI/CD 流水线4.1 GitHub Actions 集成# .github/workflows/firmware.ymlname:Build Firmwareon:push:branches:[main]pull_request:jobs:build:runs-on:ubuntu-latestcontainer:image:ghcr.io/yourorg/arm-gcc:lateststeps:-uses:actions/checkoutv4-name:Buildrun:make CROSS_COMPILEarm-none-eabi-all-name:Upload artifactsuses:actions/upload-artifactv4with:name:firmwarepath:build/*.bin4.2 GitLab CI 集成# .gitlab-ci.ymlstages:-build-test-deploybuild:stage:buildimage:yourregistry/arm-gcc:latestscript:-make CROSS_COMPILEarm-none-eabi-allartifacts:paths:-build/*.bin-build/*.elf4.3 Jenkins Pipelinepipeline{agent{docker{imageyourregistry/arm-gcc:latest}}stages{stage(Build){steps{shmake CROSS_COMPILEarm-none-eabi- all}}stage(Flash){steps{shopenocd -f board/stm32f4discovery.cfg -c program build/firmware.elf verify reset exit}}}}5. 设备端容器化运行5.1 轻量级运行时选择运行时大小适用场景Docker (moby)~100MB资源充足的边缘网关Podman~80MB无 daemon更安全containerd~30MB轻量级K8s 生态CRI-O~25MBKubernetes 专用LXC/LXD~10MB系统级容器runc~5MB最小化容器运行时5.2 balenaOS (原 resinOS)专为嵌入式/IoT 设计的容器化操作系统# balena 设备上的应用结构# 项目根目录├── docker-compose.yml ├── Dockerfile.template └── src/ └── main.py# docker-compose.yml (balena)version:2services:sensor-reader:build:.privileged:truerestart:alwayslabels:io.balena.features.kernel-modules:1data-processor:image:myregistry/processor:armv7hfdepends_on:-sensor-reader5.3 Torizon (NXP 平台)# TorizonCore 上部署应用torizoncore-builder bundle docker-compose.yml# 推送到设备torizoncore-builder images unpack torizon-core-docker-apalis-imx6-Tezi_*.tar torizoncore-builder deploy --remote-host192.168.1.100 --remote-username torizon5.4 设备端 Compose 示例# docker-compose.yml (边缘网关)version:3.8services:# MQTT Brokermosquitto:image:eclipse-mosquitto:2-opensslports:-1883:1883volumes:-./mosquitto/config:/mosquitto/config-mosquitto-data:/mosquitto/datarestart:always# 数据采集collector:build:./collectorprivileged:truedevices:-/dev/i2c-1:/dev/i2c-1-/dev/spidev0.0:/dev/spidev0.0environment:-MQTT_BROKERmosquittodepends_on:-mosquittorestart:always# 边缘推理inference:image:myregistry/edge-ai:arm64devices:-/dev/accelerator:/dev/accelerator# NPU/AI 加速器volumes:-./models:/models:rorestart:always# Web 管理界面webui:image:nginx:alpineports:-80:80volumes:-./webui:/usr/share/nginx/html:rorestart:alwaysvolumes:mosquitto-data:6. 模拟与测试6.1 QEMU 模拟嵌入式设备# 运行 ARM 虚拟机dockerrun--rm-it\--platformlinux/arm64\multiarch/ubuntu-core:arm64-focal\bash# 在容器内模拟 RISC-Vdockerrun--rm-itriscv64/ubuntu:22.04bash6.2 硬件在环测试 (HIL)# Dockerfile.hil-test FROM python:3.11-slim RUN pip install \ pyserial \ pytest \ pytest-timeout \ pyocd COPY tests/ /tests/ WORKDIR /tests CMD [pytest, --tbshort, -v]# 需要访问 USB 设备调试器dockerrun--rm\--privileged\-v/dev/bus/usb:/dev/bus/usb\-v$(pwd):/tests\hil-test6.3 网络模拟# docker-compose.network-sim.ymlversion:3.8services:device-1:build:./devicenetworks:iot-net:ipv4_address:10.0.0.10device-2:build:./devicenetworks:iot-net:ipv4_address:10.0.0.11# 模拟网关gateway:build:./gatewayports:-8080:8080networks:iot-net:ipv4_address:10.0.0.1wan-net:# 模拟云端cloud:image:nginx:alpinenetworks:wan-net:networks:iot-net:driver:bridgeipam:config:-subnet:10.0.0.0/24wan-net:driver:bridge7. 常用工具与镜像7.1 官方 社区镜像镜像用途arm32v7/ubuntuARM 32位 Ubuntuarm64v8/debianARM 64位 Debianbalenalib/%%BALENA_MACHINE_NAME%%-ubuntubalena 设备基础镜像torizon/debianTorizon 基础镜像eclipse-mosquittoMQTT Brokerhomeassistant/home-assistant智能家居nodered/node-redNode-RED 可视化编程7.2 开发工具镜像# GDB 调试dockerrun--rm-it\--privileged\-v/dev/bus/usb:/dev/bus/usb\arm-gcc\gdb-multiarch-extarget remote :3333build/firmware.elf# Wireshark 抓包分析dockerrun--rm-it\--nethost\--privileged\linuxserver/wireshark# Serial 串口调试dockerrun--rm-it\--device/dev/ttyUSB0\alpine\picocom-b115200/dev/ttyUSB08. 实战示例8.1 完整的 STM32 项目# Dockerfile.stm32 FROM ubuntu:22.04 ENV DEBIAN_FRONTENDnoninteractive RUN apt-get update apt-get install -y \ gcc-arm-none-eabi \ libnewlib-arm-none-eabi \ cmake \ make \ git \ python3 \ python3-pip \ stlink-tools \ openocd \ rm -rf /var/lib/apt/lists/* # 安装 STM32CubeMX CLI (可选) # RUN pip3 install stm32cubemx WORKDIR /project # 构建 烧录脚本 COPY scripts/build.sh scripts/flash.sh /usr/local/bin/ RUN chmod x /usr/local/bin/build.sh /usr/local/bin/flash.sh ENTRYPOINT [/bin/bash]# build.sh#!/bin/bashset-emkdir-pbuildcdbuild cmake-DCMAKE_TOOLCHAIN_FILE../cmake/arm-none-eabi.cmake..make-j$(nproc)arm-none-eabi-objcopy-Obinary firmware.elf firmware.binechoBuild complete: build/firmware.bin ($(wc-cfirmware.bin)bytes)# 使用dockerrun--rm-v$(pwd):/project stm32-dev build.sh# 烧录需要 USB 设备访问dockerrun--rm\--privileged\-v/dev/bus/usb:/dev/bus/usb\-v$(pwd):/project\stm32-dev flash.sh8.2 Raspberry Pi 应用开发# Dockerfile.rpi FROM arm64v8/python:3.11-slim RUN apt-get update apt-get install -y \ libgpiod2 \ i2c-tools \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [python3, main.py]# 在 x86 主机上构建 ARM 镜像dockerbuildx build--platformlinux/arm64-tmy-rpi-app-fDockerfile.rpi.# 推送到树莓派dockersave my-rpi-app|sshpiraspberrypidocker load# 树莓派上运行dockerrun--rm\--device/dev/i2c-1\--device/dev/gpiochip0\my-rpi-app8.3 多服务 IoT 系统# docker-compose.iot.ymlversion:3.8services:# 数据采集sensor-hub:build:./sensor-hubprivileged:trueenvironment:-SENSOR_INTERVAL5restart:always# 本地数据库influxdb:image:influxdb:1.8volumes:-influxdb-data:/var/lib/influxdbports:-8086:8086restart:always# 数据可视化grafana:image:grafana/grafana:latestports:-3000:3000volumes:-grafana-data:/var/lib/grafanaenvironment:-GF_SECURITY_ADMIN_PASSWORDadmindepends_on:-influxdbrestart:always# 规则引擎nodered:image:nodered/node-red:latestports:-1880:1880volumes:-nodered-data:/datarestart:always# 反向代理nginx:image:nginx:alpineports:-80:80volumes:-./nginx/nginx.conf:/etc/nginx/nginx.conf:rodepends_on:-grafana-noderedrestart:alwaysvolumes:influxdb-data:grafana-data:nodered-data:9. 注意事项与最佳实践9.1 资源受限设备的优化# 使用 Alpine 减小体积 FROM arm64v8/alpine:3.18 # 多阶段构建 FROM arm64v8/gcc:12 AS builder COPY . /src WORKDIR /src RUN gcc -O2 -o app main.c FROM arm64v8/alpine:3.18 COPY --frombuilder /src/app /usr/local/bin/ CMD [app] # 最终镜像可能只有 10MB9.2 安全注意事项# 安全最佳实践services:secure-app:image:my-app# 1. 不要使用 privileged尽量指定具体设备devices:-/dev/i2c-1:/dev/i2c-1# 2. 只读文件系统read_only:truetmpfs:-/tmp# 3. 非 root 用户user:1000:1000# 4. 限制资源deploy:resources:limits:memory:256Mcpus:0.5# 5. Drop 不必要的 capabilitiescap_drop:-ALLcap_add:-SYS_RAWIO# 仅在需要时9.3 存储优化# 使用 tmpfs 避免写入闪存延长存储寿命dockerrun--rm\--tmpfs/tmp:rw,noexec,nosuid,size64m\--tmpfs/var/log:rw,noexec,nosuid,size32m\my-app# 使用 overlay2 存储驱动# /etc/docker/daemon.json{storage-driver:overlay2,storage-opts:[overlay2.override_kernel_checktrue]}9.4 网络配置# 使用 host 网络模式减少开销dockerrun--rm--nethost my-iot-app# 或使用 macvlan设备看起来像独立主机dockernetwork create-dmacvlan\--subnet192.168.1.0/24\--gateway192.168.1.1\-oparenteth0\macvlan-netdockerrun--rm--netmacvlan-net--ip192.168.1.100 my-app9.5 常见陷阱陷阱解决方案镜像太大多阶段构建 Alpine 基础镜像编译太慢使用 BuildKit 缓存 ccacheUSB 设备访问--privileged或--deviceGPIO 访问--privileged--device /dev/gpiochip0时钟不同步--cap-add SYS_TIME或挂载宿主机时钟日志占满磁盘配置日志轮转--log-opt max-size10m跨架构构建慢使用docker buildx 远程 builder附录快速命令参考# 构建 ARM 镜像dockerbuildx build--platformlinux/arm64-tmy-app:arm64.# 导出镜像到离线设备dockersave my-app:arm64|gzipmy-app-arm64.tar.gzsshtargetgunzip -c my-app-arm64.tar.gz | docker load# 查看容器资源使用dockerstats# 清理无用资源dockersystem prune-a# 导出容器文件系统dockerexportmy-containerrootfs.tar# 导入为镜像catrootfs.tar|dockerimport- my-image:latest
Docker 在嵌入式设备中的常用玩法
发布时间:2026/7/11 10:38:21
Docker 在嵌入式设备中的常用玩法目录基础概念交叉编译环境固件构建与打包CI/CD 流水线设备端容器化运行模拟与测试常用工具与镜像实战示例注意事项与最佳实践1. 基础概念什么是嵌入式 Docker在嵌入式开发中Docker 主要用于环境隔离为不同项目/芯片维护独立的编译环境可复现构建确保团队成员使用完全一致的工具链CI/CD 集成在服务器上自动化构建嵌入式固件设备端部署在资源受限的设备上运行容器化应用Docker 多架构支持# 注册 QEMU 模拟器关键步骤用于构建 ARM 镜像dockerrun--rm--privilegedmultiarch/qemu-user-static--reset-pyes# 验证dockerrun--rmarm64v8/ubuntuuname-m# 输出: aarch642. 交叉编译环境2.1 统一工具链容器最常见的用法——把交叉编译工具链封装成 Docker 镜像# Dockerfile.arm-gcc FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ gcc-arm-none-eabi \ gdb-multiarch \ make \ cmake \ ninja-build \ python3 \ python3-pip \ rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /workspace # 默认进入 bash CMD [/bin/bash]使用方式# 构建镜像dockerbuild-tarm-gcc-fDockerfile.arm-gcc.# 挂载项目目录并编译dockerrun--rm-v$(pwd):/workspace arm-gcc\makeCROSS_COMPILEarm-none-eabi- all2.2 多工具链切换# Dockerfile.multi-toolchain FROM ubuntu:22.04 # ARM Cortex-M (STM32, NRF52 等) RUN apt-get update apt-get install -y gcc-arm-none-eabi # ARM Cortex-A (Linux 应用) RUN apt-get install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu # RISC-V RUN apt-get install -y gcc-riscv64-unknown-elf # MIPS RUN apt-get install -y gcc-mips-linux-gnu RUN rm -rf /var/lib/apt/lists/* WORKDIR /workspace2.3 Yocto / Buildroot 环境# Dockerfile.yocto FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ gawk wget git diffstat unzip texinfo gcc build-essential \ chrpath socat cpio python3 python3-pip python3-pexpect \ python3-git python3-jinja2 python3-subunit \ xz-utils debianutils iputils-ping \ libsdl1.2-dev xterm \ locales \ rm -rf /var/lib/apt/lists/* RUN locale-gen en_US.UTF-8 ENV LANGen_US.UTF-8 RUN useradd -m builder USER builder WORKDIR /home/builder # 克隆 Yocto RUN git clone -b kirkstone \ https://git.yoctoproject.org/poky.git /home/builder/poky3. 固件构建与打包3.1 可复现固件构建# Dockerfile.firmware-build FROM ubuntu:22.04 # 固定版本的工具链 RUN apt-get update apt-get install -y \ gcc-arm-none-eabi15:10.3-2021.10-* \ make cmake \ rm -rf /var/lib/apt/lists/* # 固定版本的构建脚本 COPY build.sh /opt/build.sh RUN chmod x /opt/build.sh WORKDIR /firmware ENTRYPOINT [/opt/build.sh]# 构建固件dockerrun--rm-v$(pwd):/firmware firmware-build:v1.0# 产出物自动落在当前目录ls-labuild/*.bin3.2 OpenWrt 构建# Dockerfile.openwrt FROM ubuntu:22.04 RUN apt-get update apt-get install -y \ build-essential ccache ecj fastjar file g gawk \ gettext git java-propose-class-default libelf-dev \ libncurses5-dev libncursesw5-dev libssl-dev \ python3 python2.7-dev python3-distutils python3-setuptools \ rsync subversion swig time unzip wget xsltproc zlib1g-dev \ rm -rf /var/lib/apt/lists/* RUN git clone https://github.com/openwrt/openwrt.git /opt/openwrt WORKDIR /opt/openwrt RUN ./scripts/feeds update -a ./scripts/feeds install -a4. CI/CD 流水线4.1 GitHub Actions 集成# .github/workflows/firmware.ymlname:Build Firmwareon:push:branches:[main]pull_request:jobs:build:runs-on:ubuntu-latestcontainer:image:ghcr.io/yourorg/arm-gcc:lateststeps:-uses:actions/checkoutv4-name:Buildrun:make CROSS_COMPILEarm-none-eabi-all-name:Upload artifactsuses:actions/upload-artifactv4with:name:firmwarepath:build/*.bin4.2 GitLab CI 集成# .gitlab-ci.ymlstages:-build-test-deploybuild:stage:buildimage:yourregistry/arm-gcc:latestscript:-make CROSS_COMPILEarm-none-eabi-allartifacts:paths:-build/*.bin-build/*.elf4.3 Jenkins Pipelinepipeline{agent{docker{imageyourregistry/arm-gcc:latest}}stages{stage(Build){steps{shmake CROSS_COMPILEarm-none-eabi- all}}stage(Flash){steps{shopenocd -f board/stm32f4discovery.cfg -c program build/firmware.elf verify reset exit}}}}5. 设备端容器化运行5.1 轻量级运行时选择运行时大小适用场景Docker (moby)~100MB资源充足的边缘网关Podman~80MB无 daemon更安全containerd~30MB轻量级K8s 生态CRI-O~25MBKubernetes 专用LXC/LXD~10MB系统级容器runc~5MB最小化容器运行时5.2 balenaOS (原 resinOS)专为嵌入式/IoT 设计的容器化操作系统# balena 设备上的应用结构# 项目根目录├── docker-compose.yml ├── Dockerfile.template └── src/ └── main.py# docker-compose.yml (balena)version:2services:sensor-reader:build:.privileged:truerestart:alwayslabels:io.balena.features.kernel-modules:1data-processor:image:myregistry/processor:armv7hfdepends_on:-sensor-reader5.3 Torizon (NXP 平台)# TorizonCore 上部署应用torizoncore-builder bundle docker-compose.yml# 推送到设备torizoncore-builder images unpack torizon-core-docker-apalis-imx6-Tezi_*.tar torizoncore-builder deploy --remote-host192.168.1.100 --remote-username torizon5.4 设备端 Compose 示例# docker-compose.yml (边缘网关)version:3.8services:# MQTT Brokermosquitto:image:eclipse-mosquitto:2-opensslports:-1883:1883volumes:-./mosquitto/config:/mosquitto/config-mosquitto-data:/mosquitto/datarestart:always# 数据采集collector:build:./collectorprivileged:truedevices:-/dev/i2c-1:/dev/i2c-1-/dev/spidev0.0:/dev/spidev0.0environment:-MQTT_BROKERmosquittodepends_on:-mosquittorestart:always# 边缘推理inference:image:myregistry/edge-ai:arm64devices:-/dev/accelerator:/dev/accelerator# NPU/AI 加速器volumes:-./models:/models:rorestart:always# Web 管理界面webui:image:nginx:alpineports:-80:80volumes:-./webui:/usr/share/nginx/html:rorestart:alwaysvolumes:mosquitto-data:6. 模拟与测试6.1 QEMU 模拟嵌入式设备# 运行 ARM 虚拟机dockerrun--rm-it\--platformlinux/arm64\multiarch/ubuntu-core:arm64-focal\bash# 在容器内模拟 RISC-Vdockerrun--rm-itriscv64/ubuntu:22.04bash6.2 硬件在环测试 (HIL)# Dockerfile.hil-test FROM python:3.11-slim RUN pip install \ pyserial \ pytest \ pytest-timeout \ pyocd COPY tests/ /tests/ WORKDIR /tests CMD [pytest, --tbshort, -v]# 需要访问 USB 设备调试器dockerrun--rm\--privileged\-v/dev/bus/usb:/dev/bus/usb\-v$(pwd):/tests\hil-test6.3 网络模拟# docker-compose.network-sim.ymlversion:3.8services:device-1:build:./devicenetworks:iot-net:ipv4_address:10.0.0.10device-2:build:./devicenetworks:iot-net:ipv4_address:10.0.0.11# 模拟网关gateway:build:./gatewayports:-8080:8080networks:iot-net:ipv4_address:10.0.0.1wan-net:# 模拟云端cloud:image:nginx:alpinenetworks:wan-net:networks:iot-net:driver:bridgeipam:config:-subnet:10.0.0.0/24wan-net:driver:bridge7. 常用工具与镜像7.1 官方 社区镜像镜像用途arm32v7/ubuntuARM 32位 Ubuntuarm64v8/debianARM 64位 Debianbalenalib/%%BALENA_MACHINE_NAME%%-ubuntubalena 设备基础镜像torizon/debianTorizon 基础镜像eclipse-mosquittoMQTT Brokerhomeassistant/home-assistant智能家居nodered/node-redNode-RED 可视化编程7.2 开发工具镜像# GDB 调试dockerrun--rm-it\--privileged\-v/dev/bus/usb:/dev/bus/usb\arm-gcc\gdb-multiarch-extarget remote :3333build/firmware.elf# Wireshark 抓包分析dockerrun--rm-it\--nethost\--privileged\linuxserver/wireshark# Serial 串口调试dockerrun--rm-it\--device/dev/ttyUSB0\alpine\picocom-b115200/dev/ttyUSB08. 实战示例8.1 完整的 STM32 项目# Dockerfile.stm32 FROM ubuntu:22.04 ENV DEBIAN_FRONTENDnoninteractive RUN apt-get update apt-get install -y \ gcc-arm-none-eabi \ libnewlib-arm-none-eabi \ cmake \ make \ git \ python3 \ python3-pip \ stlink-tools \ openocd \ rm -rf /var/lib/apt/lists/* # 安装 STM32CubeMX CLI (可选) # RUN pip3 install stm32cubemx WORKDIR /project # 构建 烧录脚本 COPY scripts/build.sh scripts/flash.sh /usr/local/bin/ RUN chmod x /usr/local/bin/build.sh /usr/local/bin/flash.sh ENTRYPOINT [/bin/bash]# build.sh#!/bin/bashset-emkdir-pbuildcdbuild cmake-DCMAKE_TOOLCHAIN_FILE../cmake/arm-none-eabi.cmake..make-j$(nproc)arm-none-eabi-objcopy-Obinary firmware.elf firmware.binechoBuild complete: build/firmware.bin ($(wc-cfirmware.bin)bytes)# 使用dockerrun--rm-v$(pwd):/project stm32-dev build.sh# 烧录需要 USB 设备访问dockerrun--rm\--privileged\-v/dev/bus/usb:/dev/bus/usb\-v$(pwd):/project\stm32-dev flash.sh8.2 Raspberry Pi 应用开发# Dockerfile.rpi FROM arm64v8/python:3.11-slim RUN apt-get update apt-get install -y \ libgpiod2 \ i2c-tools \ rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [python3, main.py]# 在 x86 主机上构建 ARM 镜像dockerbuildx build--platformlinux/arm64-tmy-rpi-app-fDockerfile.rpi.# 推送到树莓派dockersave my-rpi-app|sshpiraspberrypidocker load# 树莓派上运行dockerrun--rm\--device/dev/i2c-1\--device/dev/gpiochip0\my-rpi-app8.3 多服务 IoT 系统# docker-compose.iot.ymlversion:3.8services:# 数据采集sensor-hub:build:./sensor-hubprivileged:trueenvironment:-SENSOR_INTERVAL5restart:always# 本地数据库influxdb:image:influxdb:1.8volumes:-influxdb-data:/var/lib/influxdbports:-8086:8086restart:always# 数据可视化grafana:image:grafana/grafana:latestports:-3000:3000volumes:-grafana-data:/var/lib/grafanaenvironment:-GF_SECURITY_ADMIN_PASSWORDadmindepends_on:-influxdbrestart:always# 规则引擎nodered:image:nodered/node-red:latestports:-1880:1880volumes:-nodered-data:/datarestart:always# 反向代理nginx:image:nginx:alpineports:-80:80volumes:-./nginx/nginx.conf:/etc/nginx/nginx.conf:rodepends_on:-grafana-noderedrestart:alwaysvolumes:influxdb-data:grafana-data:nodered-data:9. 注意事项与最佳实践9.1 资源受限设备的优化# 使用 Alpine 减小体积 FROM arm64v8/alpine:3.18 # 多阶段构建 FROM arm64v8/gcc:12 AS builder COPY . /src WORKDIR /src RUN gcc -O2 -o app main.c FROM arm64v8/alpine:3.18 COPY --frombuilder /src/app /usr/local/bin/ CMD [app] # 最终镜像可能只有 10MB9.2 安全注意事项# 安全最佳实践services:secure-app:image:my-app# 1. 不要使用 privileged尽量指定具体设备devices:-/dev/i2c-1:/dev/i2c-1# 2. 只读文件系统read_only:truetmpfs:-/tmp# 3. 非 root 用户user:1000:1000# 4. 限制资源deploy:resources:limits:memory:256Mcpus:0.5# 5. Drop 不必要的 capabilitiescap_drop:-ALLcap_add:-SYS_RAWIO# 仅在需要时9.3 存储优化# 使用 tmpfs 避免写入闪存延长存储寿命dockerrun--rm\--tmpfs/tmp:rw,noexec,nosuid,size64m\--tmpfs/var/log:rw,noexec,nosuid,size32m\my-app# 使用 overlay2 存储驱动# /etc/docker/daemon.json{storage-driver:overlay2,storage-opts:[overlay2.override_kernel_checktrue]}9.4 网络配置# 使用 host 网络模式减少开销dockerrun--rm--nethost my-iot-app# 或使用 macvlan设备看起来像独立主机dockernetwork create-dmacvlan\--subnet192.168.1.0/24\--gateway192.168.1.1\-oparenteth0\macvlan-netdockerrun--rm--netmacvlan-net--ip192.168.1.100 my-app9.5 常见陷阱陷阱解决方案镜像太大多阶段构建 Alpine 基础镜像编译太慢使用 BuildKit 缓存 ccacheUSB 设备访问--privileged或--deviceGPIO 访问--privileged--device /dev/gpiochip0时钟不同步--cap-add SYS_TIME或挂载宿主机时钟日志占满磁盘配置日志轮转--log-opt max-size10m跨架构构建慢使用docker buildx 远程 builder附录快速命令参考# 构建 ARM 镜像dockerbuildx build--platformlinux/arm64-tmy-app:arm64.# 导出镜像到离线设备dockersave my-app:arm64|gzipmy-app-arm64.tar.gzsshtargetgunzip -c my-app-arm64.tar.gz | docker load# 查看容器资源使用dockerstats# 清理无用资源dockersystem prune-a# 导出容器文件系统dockerexportmy-containerrootfs.tar# 导入为镜像catrootfs.tar|dockerimport- my-image:latest