ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Streamlit 部署:demo 跑通之后,三种上线路线怎么选

Streamlit 部署:demo 跑通之后,三种上线路线怎么选

Streamlit 部署:demo 跑通之后,三种上线路线怎么选

【免费下载链接】streamlitStreamlit — A faster way to build and share data apps.项目地址: https://gitcode.com/gh_mirrors/st/streamlit

你的 Streamlit 应用在localhost:8501上跑得挺好,但同事在他的机器上打不开——Streamlit 部署的问题就从这一刻开始:应用该放到哪里、谁来托管、怎么让别人访问到。主流做法有三条:推到官方托管平台、用 Docker 容器化、或者部署到自己的服务器/云服务器。下面先给结论再展开:只发 demo 选托管平台,团队内部长期使用选容器,要自定义域名、HTTPS 和访问控制就选自有服务器。

Streamlit 三种部署方式怎么选

路线适合谁代价典型限制
官方托管平台个人 demo、快速分享给同事只需一个 Git 仓库,平台装环境、开端口、管进程免费额度有休眠和存储上限,定制能力少
Docker 容器化团队内长期使用、依赖复杂(本地模型、多语言库)写一个 Dockerfile,约 20 行需要一个能跑容器的地方:自己的 VPS 或云厂商的容器服务
自有服务器/云厂商自定义域名、HTTPS、访问控制、和现有内网打通自己管端口、防火墙、反向代理和进程守护运维工作量最大,出问题基本都自己排查

三条路线没有高下之分,只有约束不同。先想清楚"谁会访问这个应用、它要跑多久",选择自然就出来了。

路线一:官方托管,把仓库推上去就上线

最快的路径是官方托管平台:代码进 Git 仓库,平台连接你的账号、选中仓库,应用就自动构建上线,环境、端口、HTTPS 全部托管方处理,你只需要指定入口脚本(比如app.py)和依赖清单。

限制也要提前知道,决定它只适合演示和轻量应用:免费额度通常带空闲休眠(没人访问几分钟就挂起)、存储和流量上限、无法自定义域名、拿不到服务器日志。团队内部长期跑、或数据量稍大的应用,建议直接跳到下面两条路线。

路线二:Docker 打包 Streamlit 的最小 Dockerfile

容器化的核心目的是环境一致性:镜像里锁死 Python 版本和依赖版本,本地和线上跑的是同一套东西,"在我机器上是好的"这类问题直接消失。

FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8501 CMD ["streamlit", "run", "app.py", "--server.address=0.0.0.0"]

逐行看关键点:

  • FROM python:3.11-slim:基础镜像直接定死 Python 版本,和开发环境保持一致;slim 版体积小、攻击面小。
  • COPY requirements.txt .+RUN pip install:先装依赖再拷代码,依赖没变时构建可以命中缓存,不用每次重装。
  • EXPOSE 8501:Streamlit 默认端口是 8501,这个指令只是声明,真正对外的端口靠容器运行时映射,比如docker run -p 8501:8501。
  • CMD里的--server.address=0.0.0.0是全篇最关键的一个参数:监听全部网卡。缺了它,容器里 localhost 能访问、外面永远连不上。

有本地模型或多语言依赖时,在COPY . .之前多加一层RUN把对应依赖装好即可,骨架不变。

路线三:部署到云服务器,端口、反代与 HTTPS

自有服务器/云厂商路线,你要亲手管三件事:端口、反向代理、安全配置。

端口:Streamlit 默认监听 8501。云服务器的安全组(安全组/防火墙规则)和系统防火墙都要放行这个端口,只开一边都连不通。

启动:把监听地址绑到全部网卡即可,生产上不建议开热重载:

streamlit run app.py --server.address=0.0.0.0 --server.port=8501

反向代理:不要让用户直连 8501,用 nginx 监听 443,转发到本机,并转发 WebSocket 头(Streamlit 前端和后端之间走 WebSocket 通信,反代不支持 WebSocket 的话页面白屏):

location / { proxy_pass http://127.0.0.1:8501; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }

TLS 证书交给反代处理(云厂商一般有现成的证书申请流程),应用层收到的就是 HTTP,省事。

健康检查:Streamlit 自带/_stcore/health端点(实现见 lib/streamlit/web/server/starlette/starlette_routes.py),配置健康检查时直接指这个路径,成功返回 200、脚本加载失败返回 503,容器编排和监控都拿它用。

子路径与主机名:应用挂在域名子路径下(比如example.com/myapp)时,设置server.baseUrlPath = "/myapp",否则前端资源路径对不上;安全收紧时再用server.allowedHosts填允许的 Host 白名单,挡住 DNS rebinding 一类的攻击。

Streamlit 部署常见翻车现场:现象、原因与解法

现象原因解法
本地能访问,外网/同事连不上server.address未设置时默认只绑 localhost,容器里也一样启动时加--server.address=0.0.0.0
地址端口对,TCP 都连不上云安全组或系统防火墙没放行 8501两边都检查,只开一边不行
页面报错提示 XSRF token 缺失反代后页面来源和 WebSocket 来源对不上,或误关了保护反代正确转发并保留 Host 头;确需跨域时开server.enableCORS并配server.corsAllowedOrigins
本地有secrets.toml,线上取不到文件没随镜像/代码走,或路径不对敏感值改走环境变量注入,别提交进仓库;确需保留文件就挂载到.streamlit/下
健康检查一直失败检查的不是/_stcore/health,或脚本初始化就抛异常改对路径;脚本启动错误看服务日志
每次交互都重算、页面卡Streamlit 每次交互都会从头重跑整个脚本重计算加@st.cache_data;大数据集避免重复构建副本
进程挂了没人知道、也不拉起直接裸跑进程,没有守护用 systemd、supervisor 或容器托管,挂掉自动重启

上线前必查的 5 个配置

  • server.address是0.0.0.0,安全组与防火墙都已放行 8501
  • 从非本机网络访问/_stcore/health返回 200
  • 密钥、token 已移出代码库,用环境变量或挂载文件注入
  • XSRF/CORS 保持默认开启,反代场景下不裸关保护
  • 进程有守护(systemd 或容器),崩溃能自动拉起
  • 反代转发后curl -sI -N带Upgrade: websocket请求能拿到 101

再往后就是常规运维:日志接集中收集并做轮转,指标接监控平台;CI/CD 里加一步"构建镜像 → 推送 → 滚动替换",每次合并自动上线。一句话带过即可,先把上面六项过完。

下一步

今天就把发布前自检清单跑一遍,然后拿手机切到 4G 网络(或找另一台机器)直接访问线上地址:页面能开、按钮点了有反应,部署就算完成;哪一步卡住,回上面的排错表对号入座。

【免费下载链接】streamlitStreamlit — A faster way to build and share data apps.项目地址: https://gitcode.com/gh_mirrors/st/streamlit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进