使用 Docker 部署 Streamlit
简介
那么,你有一个很棒的应用,想开始与他人分享,该怎么做呢?你有几种选择。首先,你想在哪里运行 Streamlit 应用,以及如何访问它?
- 在你的企业网络中 - 大多数企业网络都是对外封闭的。你通常使用 VPN 登录企业网络并访问其中的资源。你可以出于安全原因在企业网络中的服务器上运行 Streamlit 应用,以确保只有公司内部人员可以访问它。
- 在云中 - 如果你想从企业网络外部访问你的 Streamlit 应用,或者与家庭网络或笔记本电脑外部的人分享你的应用,你可以选择此选项。在这种情况下,这将取决于你的托管提供商。我们有来自 Heroku、AWS 和其他提供商的社区提交指南。
无论你决定在哪里部署你的应用,首先都需要对其进行容器化。本指南将引导你使用 Docker 部署应用。如果你偏好 Kubernetes,请参阅使用 Kubernetes 部署 Streamlit。
先决条件
安装 Docker Engine
如果你还没有安装 Docker,请在服务器上安装。Docker 为许多 Linux 发行版(包括以下发行版)提供了 .deb
和 .rpm
包
通过运行 hello-world
Docker 镜像来验证 Docker Engine 是否正确安装
sudo docker run hello-world
提示
按照 Docker 官方的Linux 安装后步骤,以非 root 用户身份运行 Docker,这样你就不必在 docker
命令前加上 sudo
。
检查网络端口可访问性
由于你和你的用户都在企业 VPN 后面,你需要确保你们所有人都能访问某个网络端口。假设端口是 8501
,因为它是 Streamlit 使用的默认端口。请联系你的 IT 团队,请求为你和你的用户开通端口 8501
的访问权限。
创建 Dockerfile
Docker 通过读取 Dockerfile
中的指令来构建镜像。Dockerfile
是一个文本文件,包含用户在命令行中调用以组装镜像的所有命令。在Dockerfile 参考中了解更多信息。docker build
命令从 Dockerfile
构建镜像。docker run
命令首先在指定的镜像上创建一个容器,然后使用指定的命令启动它。
这是一个示例 Dockerfile
,你可以将其添加到你的目录根目录中,例如在 /app/
中
# app/Dockerfile FROM python:3.9-slim WORKDIR /app RUN apt-get update && apt-get install -y \ build-essential \ curl \ software-properties-common \ git \ && rm -rf /var/lib/apt/lists/* RUN git clone https://github.com/streamlit/streamlit-example.git . RUN pip3 install -r requirements.txt EXPOSE 8501 HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
Dockerfile 详细说明
让我们逐行讲解 Dockerfile
-
Dockerfile
必须以FROM
指令开头。它为容器设置基础镜像(可以理解为操作系统)FROM python:3.9-slim
Docker 有许多基于不同 Linux 发行版的官方 Docker 基础镜像。它们还提供包含特定语言模块(例如 Python)的基础镜像。
python
镜像有许多变种,每种都针对特定的使用场景。在这里,我们使用python:3.9-slim
镜像,它是一个轻量级镜像,包含最新版本的 Python 3.9。star 提示
你也可以使用自己的基础镜像,前提是你使用的镜像包含 Streamlit 支持的 Python 版本。使用任何特定基础镜像都没有通用的方法,也没有官方的 Streamlit 专用基础镜像。
-
WORKDIR
指令设置其后在Dockerfile
中的任何RUN
、CMD
、ENTRYPOINT
、COPY
和ADD
指令的工作目录。我们将其设置为app/
WORKDIR /app
priority_high 重要
如开发流程中所述,对于 Streamlit 1.10.0 及更高版本,Streamlit 应用无法从 Linux 发行版的根目录运行。你的主脚本应该位于根目录以外的目录中。如果你尝试从根目录运行 Streamlit 应用,Streamlit 将抛出
FileNotFoundError: [Errno 2] No such file or directory
错误。有关更多信息,请参阅 GitHub issue #5239。如果你使用的是 Streamlit 1.10.0 或更高版本,则必须将
WORKDIR
设置为根目录以外的目录。例如,你可以将WORKDIR
设置为/app
,如上面示例Dockerfile
所示。 -
安装
git
,以便我们可以从远程仓库克隆应用代码RUN apt-get update && apt-get install -y \ build-essential \ curl \ software-properties-common \ git \ && rm -rf /var/lib/apt/lists/*
-
将位于远程仓库中的代码克隆到
WORKDIR
a. 如果你的代码位于公共仓库中
RUN git clone https://github.com/streamlit/streamlit-example.git .
克隆后,
WORKDIR
的目录结构如下所示app/ - requirements.txt - streamlit_app.py
其中
requirements.txt
文件包含你的所有Python 依赖项。例如altair pandas streamlit
而
streamlit_app.py
是你的主脚本。例如from collections import namedtuple import altair as alt import math import pandas as pd import streamlit as st """ # Welcome to Streamlit! Edit `/streamlit_app.py` to customize this app to your heart's desire :heart: If you have any questions, checkout our [documentation](https://docs.streamlit.net.cn) and [community forums](https://discuss.streamlit.io). In the meantime, below is an example of what you can do with just a few lines of code: """ with st.echo(code_location='below'): total_points = st.slider("Number of points in spiral", 1, 5000, 2000) num_turns = st.slider("Number of turns in spiral", 1, 100, 9) Point = namedtuple('Point', 'x y') data = [] points_per_turn = total_points / num_turns for curr_point_num in range(total_points): curr_turn, i = divmod(curr_point_num, points_per_turn) angle = (curr_turn + 1) * 2 * math.pi * i / points_per_turn radius = curr_point_num / total_points x = radius * math.cos(angle) y = radius * math.sin(angle) data.append(Point(x, y)) st.altair_chart(alt.Chart(pd.DataFrame(data), height=500, width=500) .mark_circle(color='#0068c9', opacity=0.5) .encode(x='x:Q', y='y:Q'))
b. 如果你的代码位于私有仓库中,请阅读在构建中使用 SSH 访问私有数据并相应修改 Dockerfile -- 安装 SSH 客户端,下载 github.com 的公钥,然后克隆你的私有仓库。如果你使用替代 VCS(如 GitLab 或 Bitbucket),请查阅该 VCS 的文档,了解如何将代码复制到 Dockerfile 的
WORKDIR
中。c. 如果你的代码与 Dockerfile 在同一目录中,则将服务器上的所有应用文件(包括
streamlit_app.py
、requirements.txt
等)复制到容器中,将git clone
行替换为COPY . .
更一般地,其思想是将你的应用代码从服务器上的任何位置复制到容器中。如果代码不在 Dockerfile 所在的目录中,请修改上面的命令以包含代码路径。
-
从容器中克隆的
requirements.txt
安装你的应用Python 依赖项RUN pip3 install -r requirements.txt
-
EXPOSE
指令通知 Docker 容器在运行时监听指定的网络端口。你的容器需要监听 Streamlit 的(默认)端口 8501EXPOSE 8501
-
HEALTHCHECK
指令告诉 Docker 如何测试容器以检查它是否仍在工作。你的容器需要监听 Streamlit 的(默认)端口 8501HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
-
ENTRYPOINT
允许你配置将作为可执行文件运行的容器。在这里,它还包含应用的完整streamlit run
命令,因此你无需从命令行调用它ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
构建 Docker 镜像
docker build
命令从 Dockerfile
构建镜像。在服务器的 app/
目录中运行以下命令来构建镜像
docker build -t streamlit .
-t
标志用于标记镜像。在这里,我们将镜像标记为 streamlit
。如果你运行
docker images
你应该在 REPOSITORY 列下看到一个 streamlit
镜像。例如
REPOSITORY TAG IMAGE ID CREATED SIZE streamlit latest 70b0759a094d About a minute ago 1.02GB
运行 Docker 容器
现在你已经构建了镜像,可以通过执行以下命令来运行容器
docker run -p 8501:8501 streamlit
-p
标志将容器的端口 8501 发布到你的服务器的 8501 端口。
如果一切顺利,你应该看到类似于以下的输出
docker run -p 8501:8501 streamlit 你现在可以在浏览器中查看你的 Streamlit 应用。URL: http://0.0.0.0:8501
要查看你的应用,用户可以浏览到 http://0.0.0.0:8501
或 http://localhost:8501
注意
根据你服务器的网络配置,你可以映射到端口 80/443,以便用户可以使用服务器 IP 或主机名查看你的应用。例如:http://your-server-ip:80
或 http://your-hostname:443
。
还有其他问题?
我们的 论坛 充满有用的信息和 Streamlit 专家。