Deploy Streamlit using Docker

所以,你有一个很棒的应用,你想开始与其他人分享它,你该怎么做?你有几个选择。首先,你想在哪里运行你的Streamlit应用,以及你想如何访问它?

  • 在您的企业网络上 - 大多数企业网络对外部世界是封闭的。您通常使用VPN登录到您的企业网络并访问那里的资源。出于安全原因,您可以在企业网络中的服务器上运行您的Streamlit应用程序,以确保只有公司内部的人员可以访问它。
  • 在云端 - 如果您希望从公司网络外部访问您的Streamlit应用程序,或者与家庭网络或笔记本电脑外部的人员共享您的应用程序,您可能会选择此选项。在这种情况下,这将取决于您的主机提供商。我们有来自Heroku、AWS和其他提供商的社区提交的指南

无论您决定在哪里部署您的应用程序,您首先需要将其容器化。本指南将引导您使用Docker部署您的应用程序。如果您更喜欢Kubernetes,请参阅使用Kubernetes部署Streamlit

  1. 安装 Docker 引擎
  2. 检查网络端口可访问性

如果您还没有这样做,请在您的服务器上安装Docker。Docker 提供了许多 Linux 发行版的 .deb.rpm 包,包括:

通过运行hello-world Docker 镜像来验证 Docker Engine 是否正确安装:

sudo docker run hello-world
star

提示

按照Docker官方的Linux安装后步骤,以非root用户身份运行Docker,这样你就不必在docker命令前加上sudo

由于您和您的用户位于公司VPN后面,您需要确保所有人都能访问某个网络端口。假设端口8501,因为这是Streamlit使用的默认端口。请联系您的IT团队,并请求为您和您的用户开放端口8501的访问权限。

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的内容:

  1. 一个 Dockerfile 必须以一个 FROM 指令开始。它为容器设置了 基础镜像(可以理解为操作系统):

    FROM python:3.9-slim

    Docker 有许多基于不同 Linux 发行版的官方 Docker 基础镜像。它们还提供了带有特定语言模块的基础镜像,例如 Pythonpython 镜像有多种版本,每个版本都设计用于特定的用例。在这里,我们使用 python:3.9-slim 镜像,这是一个轻量级的镜像,带有最新版本的 Python 3.9。

    star

    提示

    你也可以使用自己的基础镜像,只要你使用的镜像包含 Streamlit 支持的 Python 版本。使用任何特定的基础镜像并没有一种适用于所有情况的方法,也没有官方的 Streamlit 专用基础镜像。

  2. WORKDIR 指令为 Dockerfile 中任何后续的 RUNCMDENTRYPOINTCOPYADD 指令设置工作目录。让我们将其设置为 app/

    WORKDIR /app
    priority_high

    重要

    开发流程 中所述,对于 Streamlit 1.10.0 及更高版本,Streamlit 应用程序不能从 Linux 发行版的根目录运行。您的主脚本应位于根目录以外的目录中。如果您尝试从根目录运行 Streamlit 应用程序,Streamlit 将抛出 FileNotFoundError: [Errno 2] No such file or directory 错误。有关更多信息,请参阅 GitHub 问题 #5239

    如果您使用的是 Streamlit 1.10.0 或更高版本,则必须将 WORKDIR 设置为根目录以外的目录。例如,您可以像上面的示例 Dockerfile 中所示,将 WORKDIR 设置为 /app

  3. 安装 git,以便我们可以从远程仓库克隆应用程序代码:

    RUN apt-get update && apt-get install -y \ build-essential \ curl \ software-properties-common \ git \ && rm -rf /var/lib/apt/lists/*
  4. Clone your code that lives in a remote repo to WORKDIR:

    a. If your code is in a public repo:

    RUN git clone https://github.com/streamlit/streamlit-example.git .

    Once cloned, the directory of WORKDIR will look like the following:

    app/ - requirements.txt - streamlit_app.py

    where requirements.txt file contains all your Python dependencies. E.g

    altair pandas streamlit

    and streamlit_app.py is your main script. E.g.

    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.io) 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. If your code is in a private repo, please read Using SSH to access private data in builds and modify the Dockerfile accordingly -- to install an SSH client, download the public key for github.com, and clone your private repo. If you use an alternative VCS such as GitLab or Bitbucket, please consult the documentation for that VCS on how to copy your code to the WORKDIR of the Dockerfile.

    c. If your code lives in the same directory as the Dockerfile, copy all your app files from your server into the container, including streamlit_app.py, requirements.txt, etc, by replacing the git clone line with:

    COPY . .

    More generally, the idea is copy your app code from wherever it may live on your server into the container. If the code is not in the same directory as the Dockerfile, modify the above command to include the path to the code.

  5. 在容器中从克隆的requirements.txt安装你的应用程序的Python依赖项

    RUN pip3 install -r requirements.txt
  6. EXPOSE 指令告诉 Docker 容器在运行时监听指定的网络端口。您的容器需要监听 Streamlit 的(默认)端口 8501:

    EXPOSE 8501
  7. HEALTHCHECK 指令告诉 Docker 如何测试容器以检查它是否仍在工作。您的容器需要监听 Streamlit 的(默认)端口 8501:

    HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
  8. 一个ENTRYPOINT允许你配置一个将作为可执行文件运行的容器。在这里,它还包含了你的应用程序的整个streamlit run命令,因此你不需要从命令行调用它:

    ENTRYPOINT ["streamlit", "run", "streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]

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 run -p 8501:8501 streamlit

-p 标志将容器的8501端口发布到服务器的8501端口。

如果一切顺利,你应该会看到类似于以下的输出:

docker run -p 8501:8501 streamlit You can now view your Streamlit app in your browser. URL: http://0.0.0.0:8501

要查看您的应用程序,用户可以浏览到 http://0.0.0.0:8501http://localhost:8501

push_pin

注意

根据您服务器的网络配置,您可以映射到端口80/443,以便用户可以使用服务器IP或主机名查看您的应用程序。例如:http://your-server-ip:80http://your-hostname:443

forum

还有问题吗?

我们的 论坛 充满了有用的信息和Streamlit专家。