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),仅供参考