You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Docker容器中实现flask-serial正常运行?

Docker部署Flask串口应用后无法接收UART数据的问题

我用Python和Flask开发了一个Web应用,用来展示通过UART接收的数据,原本在Raspberry Pi Zero上运行正常,依赖flask-serial模块处理串口连接。但改成Docker镜像部署(搭配Nginx处理SSL证书、gunicorn预编译脚本提升性能)后,串口消息无法转发到Python脚本和flask-serial。尝试过参考pyserial的教程修复,但pyserial在Flask项目中无法正常工作。


相关代码配置

主脚本代码

import os
from   flask_migrate import Migrate
from   flask_minify  import Minify
from   sys import exit
from   apps import create_app, db
from   flask_serial import Serial

app = create_app(app_config)
Migrate(app, db)
ser = Serial(app)

# 处理UART消息
@ser.on_message()
def handle_message(msg):
    # 业务逻辑处理

apps/init.py 内容

from flask import Flask

def create_app(config):
    app = Flask(__name__)

    # flask_serial插件配置
    app.config['SERIAL_TIMEOUT'] = 0.2
    app.config['SERIAL_PORT'] = '/dev/ttyS0'
    app.config['SERIAL_BAUDRATE'] = 115200
    app.config['SERIAL_BYTESIZE'] = 8
    app.config['SERIAL_PARITY'] = 'N'
    app.config['SERIAL_STOPBITS'] = 1

    register_extensions(app)
    register_blueprints(app)
    configure_database(app)

    return app

docker-compose.yaml 内容

version: '3.3'
services:
  mywebapp:
    container_name: mywebapp
    restart: always
    env_file: .env
    build: .
    networks:
      - db_network
      - web_network
    volumes:
      - /dev:/dev
    privileged: true
    tty: true
  nginx:
    container_name: nginx
    restart: always
    image: "nginx:latest"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./certs:/etc/ssl/certs
    networks:
      - web_network
    depends_on: 
      - mywebapp
networks:
  db_network:
    driver: bridge
  web_network:
    driver: bridge

Dockerfile 内容

FROM python:3.9
# 设置环境变量
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY requirements.txt .
# 安装Python依赖
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# 启动gunicorn
CMD ["gunicorn", "--config", "gunicorn-cfg.py", "run:app"]

启动命令

docker-compose up --build

可能的解决思路

  1. 检查串口设备权限
    虽然已挂载/dev:/dev并开启privileged: true,但容器内用户可能没有访问/dev/ttyS0的权限。可在Dockerfile中添加:

    RUN usermod -aG dialout root
    

    或者进入容器手动执行chmod 666 /dev/ttyS0测试权限是否正常。

  2. 解决gunicorn多进程冲突
    flask-serial的串口监听是单进程模式,gunicorn默认多worker进程会导致多个进程抢占串口资源。修改gunicorn-cfg.py,强制设置单worker:

    workers = 1
    
  3. 验证容器内串口可用性
    进入容器执行命令,确认串口设备存在且可访问:

    docker exec -it mywebapp bash
    # 查看设备是否存在
    ls -l /dev/ttyS0
    # 用pyserial测试连接
    python -c "import serial; ser = serial.Serial('/dev/ttyS0', 115200); print(ser.is_open); ser.close()"
    
  4. 调整flask-serial初始化时机
    将Serial的初始化和消息处理函数移到create_app内部,确保与Flask上下文绑定:

    # 修改apps/__init__.py
    from flask_serial import Serial
    
    def create_app(config):
        app = Flask(__name__)
        # ... 原有配置 ...
        ser = Serial(app)
    
        @ser.on_message()
        def handle_message(msg):
            # 业务逻辑处理
        # ... 其他注册操作 ...
        return app
    
  5. 确认串口设备路径正确性
    Raspberry Pi Zero的UART设备可能是/dev/ttyAMA0而非/dev/ttyS0(取决于蓝牙是否占用串口)。在宿主机执行ls -l /dev/serial/by-id/确认实际设备路径,再修改app配置中的串口路径。


内容的提问来源于stack exchange,提问作者sieller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:07:13