Docker Compose编排物联网平台后端:Nginx+PHP-FPM+EMQX+InfluxDB一键部署实战
2026/8/24 20:08:08 网站建设 项目流程

Docker Compose编排物联网平台后端:Nginx+PHP-FPM+EMQX+InfluxDB一键部署实战

物联网平台后端涉及的服务组件多,手动部署一次就得折腾半天。Nginx做反向代理,PHP-FPM跑业务API,EMQX处理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端口直达EMQX,Web端WebSocket走Nginx代理到EMQX的8083端口。PHP-FPM只对内部网络开放,不直接暴露。

docker-compose.yml完整配置yamlversion: "3.8"services: 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_HOST=influxdb - DB_PORT=8086 - DB_TOKEN=${INFLUX_TOKEN} - DB_ORG=${INFLUX_ORG} - DB_BUCKET=${INFLUX_BUCKET} - REDIS_HOST=redis - REDIS_PORT=6379 - MQTT_HOST=emqx - MQTT_PORT=1883 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_NAME=iot-emqx - EMQX_HOST=emqx - 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_MODE=setup - 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_USER=adminINFLUX_PASSWORD=ChangeMeInProduction2026INFLUX_ORG=huwangkejiINFLUX_BUCKET=iot_dataINFLUX_TOKEN=your-influxdb-token-hereEMQX_DASHBOARD_PASSWORD=ChangeMeAlso2026.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"虎王科技的物联网平台开源项目和更多部署实战经验可以在GitHub(github.com/huwangkeji)找到,博客(heicat.com)上有Docker和PHP相关的技术笔记。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询