Docker Compose编排物联网平台后端:Nginx+PHP-FPM+EMQX+InfluxDB一键部署实战 Docker Compose编排物联网平台后端NginxPHP-FPMEMQXInfluxDB一键部署实战物联网平台后端涉及的服务组件多手动部署一次就得折腾半天。Nginx做反向代理PHP-FPM跑业务APIEMQX处理MQTT设备连接InfluxDB存时序数据Redis做缓存。每个组件单独装、单独配环境一换全得重来。Docker Compose能把这套东西用一份YAML文件定义清楚一条命令拉起来。本文分享沧州虎王科技在物联网平台部署中使用的Docker Compose编排方案经过生产环境验证可以直接拿去改。### 整体架构平台后端的服务拓扑| 服务 | 镜像 | 端口 | 职责 || — | — | — | — || Nginx | nginx:1.25-alpine | 80, 443 | 反向代理静态资源SSL终结 || PHP-FPM | php:8.2-fpm-alpine | 9000 | 业务API设备管理数据查询 || EMQX | emqx/emqx:5.4 | 1883, 8083, 18083 | MQTT Broker设备接入 || InfluxDB | influxdb:2.7 | 8086 | 时序数据存储 || Redis | redis:7-alpine | 6379 | 会话缓存设备状态 |Nginx对外暴露80/443端口所有外部请求经过它。设备端MQTT连接走1883端口直达EMQXWeb端WebSocket走Nginx代理到EMQX的8083端口。PHP-FPM只对内部网络开放不直接暴露。docker-compose.yml完整配置yamlversion: 3.8services: nginx: image: nginx:1.25-alpine container_name: iot-nginx restart: unless-stopped ports: - 80:80 - 443:443 volumes: - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./src:/var/www/html:ro - ./logs/nginx:/var/log/nginx - ./ssl:/etc/nginx/ssl:ro depends_on: - php-fpm networks: - iot-net php-fpm: build: context: ./php dockerfile: Dockerfile container_name: iot-php restart: unless-stopped volumes: - ./src:/var/www/html - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro environment: - DB_HOSTinfluxdb - DB_PORT8086 - DB_TOKEN${INFLUX_TOKEN} - DB_ORG${INFLUX_ORG} - DB_BUCKET${INFLUX_BUCKET} - REDIS_HOSTredis - REDIS_PORT6379 - MQTT_HOSTemqx - MQTT_PORT1883 depends_on: - influxdb - redis - emqx networks: - iot-net emqx: image: emqx/emqx:5.4 container_name: iot-emqx restart: unless-stopped ports: - 1883:1883 - 8083:8083 - 18083:18083 environment: - EMQX_NAMEiot-emqx - EMQX_HOSTemqx - EMQX_DASHBOARD__DEFAULT_PASSWORD${EMQX_DASHBOARD_PASSWORD} volumes: - emqx-data:/opt/emqx/data - emqx-etc:/opt/emqx/etc networks: - iot-net influxdb: image: influxdb:2.7 container_name: iot-influxdb restart: unless-stopped ports: - 8086:8086 environment: - DOCKER_INFLUXDB_INIT_MODEsetup - DOCKER_INFLUXDB_INIT_USERNAME${INFLUX_USER} - DOCKER_INFLUXDB_INIT_PASSWORD${INFLUX_PASSWORD} - DOCKER_INFLUXDB_INIT_ORG${INFLUX_ORG} - DOCKER_INFLUXDB_INIT_BUCKET${INFLUX_BUCKET} - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN${INFLUX_TOKEN} volumes: - influxdb-data:/var/lib/influxdb2 networks: - iot-net redis: image: redis:7-alpine container_name: iot-redis restart: unless-stopped command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru ports: - 6379:6379 volumes: - redis-data:/data networks: - iot-netvolumes: emqx-data: emqx-etc: influxdb-data: redis-data:networks: iot-net: driver: bridge配置里有几个设计决策值得说明。第一PHP-FPM用自定义Dockerfile构建因为官方镜像不带PDO、Redis等扩展需要额外安装。第二所有敏感信息通过环境变量注入变量值放在同目录的.env文件里不写进docker-compose.yml。第三Nginx和PHP-FPM共享同一个代码卷./src但Nginx以只读方式挂载:ro防止Nginx意外修改代码。PHP-FPM的DockerfiledockerfileFROM php:8.2-fpm-alpineRUN apk add --no-cache \ libzip-dev \ libxml2-dev \ oniguruma-dev \ docker-php-ext-install \ pdo_mysql \ pdo \ simplexml \ zip \ opcache \ pecl install redis influxdb \ docker-php-ext-enable redis influxdbCOPY php.ini /usr/local/etc/php/conf.d/custom.iniWORKDIR /var/www/html这个Dockerfile基于Alpine Linux最终镜像体积约120MB。opcache默认启用对PHP API性能提升明显。influxdb扩展是PHP的原生InfluxDB客户端比用cURL手写HTTP请求效率高。### Nginx反向代理配置Nginx需要处理三类请求PHP API请求、MQTT WebSocket连接、静态资源。nginxupstream php-fpm { server php-fpm:9000;}upstream emqx-ws { server emqx:8083;}server { listen 80; server_name iot.example.com; location /static/ { root /var/www/html; expires 30d; access_log off; } location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_pass php-fpm; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; fastcgi_read_timeout 30s; } location /mqtt { proxy_pass http://emqx-ws; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_read_timeout 300s; }}MQTT over WebSocket的配置最容易出错。proxy_set_header Upgrade和Connection这两个头必须加否则WebSocket握手会失败。proxy_read_timeout设到300秒因为MQTT连接是长连接默认的60秒超时会导致设备频繁断开重连。### .env环境变量文件bashINFLUX_USERadminINFLUX_PASSWORDChangeMeInProduction2026INFLUX_ORGhuwangkejiINFLUX_BUCKETiot_dataINFLUX_TOKENyour-influxdb-token-hereEMQX_DASHBOARD_PASSWORDChangeMeAlso2026.env文件不要提交到Git仓库加到.gitignore里。生产环境的密码和Token应该通过CI/CD流水线注入而不是写在文件里。一键启动与验证bashdocker compose up -ddocker compose psdocker compose logs -f php-fpm启动后用curl验证各服务是否正常bashcurl http://localhost/healthcurl http://localhost:8086/healthcurl http://localhost:18083/api/v5/statusdocker exec iot-redis redis-cli ping### PHP连接各服务的代码示例php?phpfunction writeDeviceData($deviceId, $field, $value) { $client new InfluxDB\Client(getenv(DB_HOST), getenv(DB_PORT)); $database $client-selectDB(getenv(DB_BUCKET)); $point new InfluxDB\Point( device_metrics, null, [device_id $deviceId], [$field floatval($value)], time() ); $database-writePoints([$point], InfluxDB\Database::PRECISION_SECONDS);}function setDeviceOnline($deviceId) { $redis new Redis(); $redis-connect(getenv(REDIS_HOST), getenv(REDIS_PORT)); $redis-setex(device:online:$deviceId, 300, json_encode([ last_seen date(c), ip $_SERVER[REMOTE_ADDR] ?? unknown ]));}function sendMqttCommand($deviceId, $command) { $mqtt new PhpMqtt\Client\MqttClient( getenv(MQTT_HOST), intval(getenv(MQTT_PORT)), php-backend- . uniqid() ); $mqtt-connect(); $mqtt-publish(device/$deviceId/cmd, json_encode($command), 1); $mqtt-disconnect();}这段代码展示了三个后端服务的调用方式。InfluxDB写数据点Redis设带过期时间的在线状态MQTT发布控制指令。实际项目中MQTT连接应该用连接池复用不要每次请求都新建连接。### 生产环境优化建议第一给PHP-FPM配置合理的进程数。默认的dynamic模式下pm.max_children设为50对于中小规模物联网平台够用。如果设备连接数超过5000建议改用static模式并把pm.max_children提到100-200同时给容器分配2GB以上内存。第二EMQX的连接数上限需要调整。默认配置支持10万连接但内存只有2GB的话实际能撑3-5万。在emqx.conf里修改node.process_limit和listeners.tcp.default.max_connections。第三InfluxDB的存储空间规划。1000台设备每秒上报一个数据点一天8640万条约占5GB存储。用InfluxDB的连续查询做自动降采样把超过7天的原始数据降精度到1分钟聚合。第四日志收集用ELK或者Loki别让日志文件在容器里无限增长。在docker-compose.yml里给每个服务加logging配置限制日志大小yamllogging: driver: json-file options: max-size: 10m max-file: 3虎王科技的物联网平台开源项目和更多部署实战经验可以在GitHubgithub.com/huwangkeji找到博客heicat.com上有Docker和PHP相关的技术笔记。

相关新闻

最新新闻

桌面AI应用部署与测试全指南:从环境准备到功能验证

桌面AI应用部署与测试全指南:从环境准备到功能验证

这次我们来看一个名为“A desktop fly drawn to the scent of vibecode”的项目。从标题直译来看,它像是一个被“vibecode”气味吸引的桌面“苍蝇”,听起来有些抽象。结合当前AI和SaaS的热潮,以及“desktop”这个高频词,这个项目很…

2026/8/24 20:53:32
本地音频处理项目部署指南:从环境准备到功能验证全流程

本地音频处理项目部署指南:从环境准备到功能验证全流程

这次我们来看一个名为“無地歌, 非正弦ソウ”的项目,其核心是围绕“プロトコル”和“タキナビキ”这两个关键词展开的。从项目标题和命名风格来看,这很可能是一个涉及音频处理、音乐生成或某种特定数据协议的本地化工具或模型。对于技术爱好者而言&#…

2026/8/24 20:53:32
如何用 ncmdump:一次拖拽完成 NCM 转 MP3 批量转换

如何用 ncmdump:一次拖拽完成 NCM 转 MP3 批量转换

如何用 ncmdump:一次拖拽完成 NCM 转 MP3 批量转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 刚从网易云下好的歌,车机却弹出"格式不支持",问题出在 .ncm 这个后缀上。用 ncmdump …

2026/8/24 20:53:32
基于FFmpeg的跨平台视频音频合并方案:兼容国产系统与自动化实践

基于FFmpeg的跨平台视频音频合并方案:兼容国产系统与自动化实践

1. 背景与核心概念 在内容创作、教育培训、自媒体运营等场景中,我们经常需要将一段视频与背景音乐进行合成。无论是为旅行Vlog添加氛围音乐,还是为教学视频配上解说音轨,这都是一项高频需求。然而,当开发环境或目标用户群体横跨不…

2026/8/24 20:53:32
本地一键生成短剧视频:基于MiniMax-H3与ComfyUI的自动化工作流实践

本地一键生成短剧视频:基于MiniMax-H3与ComfyUI的自动化工作流实践

这次我们来看一个能让你在本地电脑上,一键生成短剧视频的项目。它叫 MiniMax-H3 ,结合了强大的多模态大模型能力和 ComfyUI 的可视化工作流,目标是实现从剧本到成片的“全自动”处理。你不用再手动找参考图、拆解分镜、逐帧调整&#xff0c…

2026/8/24 20:53:32
鸣潮wuwa-mod怎么装?5步用上15个免肝神器

鸣潮wuwa-mod怎么装?5步用上15个免肝神器

鸣潮wuwa-mod怎么装?5步用上15个免肝神器 【免费下载链接】wuwa-mod Wuthering Waves pak mods 项目地址: https://gitcode.com/GitHub_Trending/wu/wuwa-mod wuwa-mod 是给《鸣潮》做的一套 .pak 模组包,技能无冷却、无限体力、自动拾取这些功能…

2026/8/24 20:48:31