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

在AWS EC2上用Streamlit运行Dash仪表盘遇主线程信号错误求助

问题

我用Python 3.7.10开发了基于Dash和matplotlib的仪表盘,代码文件为index.py。尝试部署到AWS EC2实例时,已完成以下操作:

  • 执行chmod 400 web04-test.pem配置密钥文件权限
  • 通过ssh -i "web04-test.pem" ec2-user@ec2-43-206-106-106.ap-northeast-1.compute.amazonaws.com连接EC2实例
  • 切换至root用户,执行系统更新并安装Git
  • 克隆GitHub仓库:git clone https://github.com/*****/web04-test.git
  • 进入项目目录后,通过pip安装dash、pandas、matplotlib、streamlit、networkx等依赖包
  • 执行python3 -m streamlit run index.py启动仪表盘

启动后出现如下错误:

ValueError: signal only works in main thread
Traceback:
File "/usr/local/lib/python3.7/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 563, in _run_script
    exec(code, module.__dict__)
File "/home/ec2-user/web04-test/index.py", line 422, in <module>
    app.run_server(debug=True)
File "/usr/local/lib/python3.7/site-packages/dash/dash.py", line 2133, in run_server
    self.run(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/dash/dash.py", line 1980, in run
    self.server.run(host=host, port=port, debug=debug, **flask_run_options)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1188, in run
    run_simple(t.cast(str, host), port, self, **options)
File "/usr/local/lib/python3.7/site-packages/werkzeug/serving.py", line 1095, in run_simple
    reloader_type=reloader_type,
File "/usr/local/lib/python3.7/site-packages/werkzeug/_reloader.py", line 427, in run_with_reloader
    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
File "/usr/lib64/python3.7/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))

index.py核心代码:

import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input , Output, State
import plotly.graph_objs as go
import pandas as pd
import datetime

...
app = dash.Dash(__name__ )
app.layout = html.Div([...])
...
if __name__ =='__main__':
    app.run_server(debug=True)

请问如何修复该错误,正常显示仪表盘?


解决方案

核心原因

你错误地用Streamlit启动Dash应用,两者是独立的Web框架,混用会导致线程冲突:Dash的run_server(debug=True)会启动Flask的调试重载器,而Streamlit本身运行在非主线程中,重载器尝试注册信号处理时就会触发signal only works in main thread错误。

修复步骤

  1. 修改启动方式与代码参数
    放弃用Streamlit启动,直接用Python运行Dash应用,并调整run_server参数:

    • 修改index.py中的启动代码:
      if __name__ =='__main__':
          app.run_server(debug=False, host='0.0.0.0', port=8050)
      
      • host='0.0.0.0':允许EC2外部访问
      • debug=False:禁用调试重载器,彻底避免线程信号问题(生产环境必须关闭调试模式)
      • port=8050:Dash默认端口,可按需修改
    • 在EC2终端执行启动命令:
      python3 index.py
      
  2. 配置EC2安全组
    在AWS控制台的EC2实例安全组中添加入站规则:

    • 类型:自定义TCP
    • 端口范围:8050(或你设置的端口)
    • 源:可设为0.0.0.0/0(允许所有IP访问),或限制为你的本地IP提升安全性
  3. 验证访问
    启动应用后,通过EC2公网IP访问:http://ec2-43-206-106-106.ap-northeast-1.compute.amazonaws.com:8050

额外建议

  • 如果要使用Streamlit部署,需重构代码为Streamlit风格,而非直接运行Dash应用
  • 生产环境建议用Gunicorn或uWSGI等WSGI服务器托管Dash应用,替代直接用run_server:
    gunicorn -w 4 -b 0.0.0.0:8050 index:server
    
    其中index:server指index.py中的app.server对象(Dash基于Flask,app.server是底层Flask实例)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:01:01