Docker容器化部署实战:物联网平台从开发到生产的完整路径

Docker容器化部署实战:物联网平台从开发到生产的完整路径

"在我机器上能跑"这句话在物联网项目里出现的频率比任何其他领域都高。开发环境用Ubuntu 22.04,生产服务器跑CentOS 7,PHP版本差一个minor,扩展依赖不一致,部署当天晚上就得加班排障。Docker解决的就是这个问题。

这篇文章不讲Docker的基础概念,直接上物联网平台的容器化部署实战。从Dockerfile编写、docker-compose编排、到生产环境的镜像构建和CI/CD流水线,每一步都附带可直接复用的配置和踩坑记录。

一、为什么物联网平台特别需要Docker

物联网平台的部署环境多样。有的部署在云服务器上,有的跑在工业网关的ARM板上,有的部署在客户自有的内网机房。不同环境的操作系统、CPU架构、软件版本各不相同。

Docker的核心价值在这种场景下特别明显:

痛点 传统部署 Docker部署
环境不一致 手动安装依赖,版本漂移 镜像锁定环境,到处一致
多服务依赖 手动启动顺序,容易遗漏 compose编排,一键启动
回滚困难 需要手动卸载和重装 切换镜像tag即可
资源隔离 服务共享资源,互相干扰 每个容器独立资源限制

二、Dockerfile实战

2.1 PHP后端镜像

物联网平台的后端常用PHP。以下是一个生产级PHP-FPM镜像的Dockerfile:

FROM php:8.2-fpm-alpine

# 安装系统依赖和PHP扩展
RUN apk add --no-cache \
    libzip-dev \
    libxml2-dev \
    curl-dev \
    && docker-php-ext-install \
    pdo_mysql \
    zip \
    xml \
    bcmath \
    opcache

# 配置OPcache
RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini \
    && echo "opcache.memory_consumption=256" >> /usr/local/etc/php/conf.d/opcache.ini \
    && echo "opcache.max_accelerated_files=20000" >> /usr/local/etc/php/conf.d/opcache.ini

# 设置工作目录
WORKDIR /var/www/html

# 复制代码
COPY . /var/www/html

# 设置权限
RUN chown -R www-data:www-data /var/www/html \
    && chmod -R 755 /var/www/html

EXPOSE 9000

2.2 前端Nginx镜像

FROM nginx:alpine

# 复制自定义Nginx配置
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

# 复制前端构建产物
COPY ./dist /usr/share/nginx/html

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

2.3 多阶段构建优化

生产镜像应该尽量小。用多阶段构建,把编译和运行分开:

# 阶段1:构建前端
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 阶段2:运行Nginx
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80

多阶段构建的好处是最终镜像不包含Node.js运行时和node_modules,镜像体积从800MB降到50MB以下。

三、docker-compose编排

物联网平台通常包含多个服务:PHP后端、Nginx前端、MySQL数据库、Redis缓存、MQTT消息中间件。用docker-compose一键编排:

version: '3.8'

services:
  nginx:
    build: ./docker/nginx
    ports:
      - "80:80"
    depends_on:
      - php
    volumes:
      - ./src:/var/www/html
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    networks:
      - iot_net

  php:
    build: ./docker/php
    volumes:
      - ./src:/var/www/html
    depends_on:
      - mysql
      - redis
    networks:
      - iot_net

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: ${DB_NAME}
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - iot_net

  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    ports:
      - "6379:6379"
    networks:
      - iot_net

  mosquitto:
    image: eclipse-mosquitto:2
    ports:
      - "1883:1883"
      - "9001:9001"
    volumes:
      - ./docker/mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf
    networks:
      - iot_net

volumes:
  mysql_data:
  redis_data:

networks:
  iot_net:
    driver: bridge

3.1 环境变量管理

开发环境和生产环境的配置不同,不应该硬编码在compose文件里。用.env文件管理:

# .env.development
DB_ROOT_PASSWORD=dev_root_pass
DB_NAME=iot_platform
DB_USER=iot_user
DB_PASSWORD=dev_pass

# .env.production
DB_ROOT_PASSWORD=prod_strong_password
DB_NAME=iot_platform
DB_USER=iot_user
DB_PASSWORD=prod_strong_pass

启动时指定环境文件:

docker compose --env-file .env.production up -d

四、生产部署最佳实践

4.1 镜像版本锁定

生产环境严禁使用latest标签。latest指向的镜像会随着上游更新而变化,今天能跑明天可能就崩。在Dockerfile和compose中锁定具体版本:

mysql:
  image: mysql:8.0.36  # 而不是 mysql:latest

4.2 健康检查

生产环境必须配置健康检查,让编排系统知道容器是否真的在工作:

php:
  build: ./docker/php
  healthcheck:
    test: ["CMD", "php-fpm", "-t"]
    interval: 30s
    timeout: 10s
    retries: 3
    start_period: 30s

4.3 资源限制

物联网平台常部署在资源有限的服务器上。给每个容器设定CPU和内存上限,防止单个服务吃光所有资源:

mysql:
  image: mysql:8.0.36
  deploy:
    resources:
      limits:
        cpus: '2.0'
        memory: 1024M
      reservations:
        cpus: '0.5'
        memory: 256M

4.4 日志管理

Docker默认日志文件会无限增长。生产环境配置日志轮转:

php:
  build: ./docker/php
  logging:
    driver: "json-file"
    options:
      max-size: "10m"
      max-file: "3"

五、CI/CD流水线

用GitHub Actions(或Gitee CI)实现自动化构建和推送:

name: Build and Push IoT Platform Image

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Login to Container Registry
        run: docker login -u ${{ secrets.REG_USER }} -p ${{ secrets.REG_PASS }}

      - name: Build PHP image
        run: |
          docker build -f docker/php/Dockerfile -t iot-platform/php:latest .
          docker push iot-platform/php:latest

      - name: Build Nginx image
        run: |
          docker build -f docker/nginx/Dockerfile -t iot-platform/nginx:latest .
          docker push iot-platform/nginx:latest

六、实际项目案例

虎王科技的导航站系统anime_nav_pro_plus(gitee.com/zesso/anime_nav_pro_plus)就是一个适合Docker化部署的PHP项目。它支持后台管理、分类排序、SEO优化、静态页面生成,采用深色玻璃拟态设计。这类Web应用的Docker化步骤和我上面描述的完全一致:PHP-FPM镜像+Nginx镜像+MySQL服务,用compose编排一键启动。

实际上,物联网平台的Web管理台和导航站在技术栈上是高度一致的。PHP后端提供API、前端渲染仪表盘、MySQL存储设备数据、Redis做实时数据缓存。虎王科技在开发hardware_tool(随身WiFi调试工具)时也采用了类似的Docker化部署方案,PHP后端管理串口通信配置,前端做可视化操作界面。

6.1 ARM架构适配

物联网平台常部署在ARM架构的工业网关上(树莓派、NanoPi等)。Docker支持多架构镜像构建:

# 构建多架构镜像
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t iot-platform/php:latest \
  --push .

这样同一镜像可以在x86服务器和ARM网关上运行,开发环境和生产环境的镜像完全一致。

七、常见部署问题

权限问题 :PHP容器以www-data用户运行,挂载的宿主机目录权限不对会导致写入失败。解决方案是compose中指定user参数,或者用init容器在启动时修正权限。

时区问题 :容器默认UTC时区,国内业务需要改为Asia/Shanghai。在Dockerfile中添加:

RUN apk add --no-cache tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

MySQL初始化 :MySQL容器首次启动时执行SQL脚本,把文件放到/docker-entrypoint-initdb.d/目录下即可自动执行建表和初始数据导入。


Docker在物联网平台部署中的价值不是"跟上潮流",而是实打实地解决环境一致性、依赖隔离和快速回滚三大痛点。上面的配置都是从实际项目里沉淀出来的,直接拿去用能省不少排坑时间。觉得有用的话点个赞存一下,后续会补上K8s编排和监控告警的实践,关注了第一时间收到更新。

posted @ 2026-09-26 00:01  虎王科技  阅读(1)  评论(0)    收藏  举报