简要说明
Streamlit 是一个很棒的工具,可以轻松创建漂亮的 data 应用程序,但要部署这些应用程序并使其可以访问,对于非专业人员来说可能会比较复杂。在本文中,我们将介绍在 GCP 上部署应用程序的过程,以确保限制特定人员的访问权限。我们实施了两种解决方案:一种是使用 Cloud Run,另一种是使用 App Engine,我们选择使用 App Engine,因为它易于使用 IAP(身份感知代理)确保应用程序的安全。.

中号 Blog by Artefact。.

本文最初发表于 Medium.com.
在我们的 Medium Blog 上关注我们!

部署动机

在本文中,我们将以文本 Data 浏览器为例,这是我们开发的一款 Streamlit 应用程序,目的是在几分钟内点击几下即可深入了解原始文本 data。该应用程序将在今后的文章中介绍。.

Example of the app that will be deployed on GCP

将在 GCP 上部署的应用程序示例

启动此应用程序和此进程有两个主要选项:

  • 用户要么在自己的电脑上克隆 GitHub 仓库,安装所有依赖项,然后在本地环境中启动应用程序。.

  • 或者,用户可以使用专用 URL 直接访问应用程序,而无需事先安装。.

为了让公司内最多的人,也就是那些不一定习惯于使用 GitHub 的人都能使用该应用程序,我们决定在 GCP(谷歌云平台)上部署该应用程序,并在安全的环境中通过单一 URL 进行访问。.

在 GCP 上逐步部署

我们测试了在 GCP 上部署应用程序的两种不同方法:

  • 使用云运行

  • 使用应用程序引擎

不过,这两种方法都有一个初步的共同步骤,那就是应用程序的 “docker 化”。.

应用程序的 Docker 化

如果您对 Docker 还不熟悉,这里有一个小介绍,但请不要犹豫,马上查看 文献资料 或更多具体文章了解更多详情。.

什么是 docker?

Docker 是一个用于开发、发布和运行应用程序的开放平台。它允许你将应用程序及其所有依赖项打包成一个标准化的软件开发单元。在实践中,这涉及到构建所谓的 Docker 映像,即构成 Docker 容器基础的应用程序蓝图,也就是静态内容。为了构建该映像,我们需要定义一个 Dockerfile,即一个简单的文本文件,其中包含 Docker 客户端在创建映像时调用的命令列表。创建完成后,映像将存储在注册表(如 GCP 上的容器注册表)中,并可通过 Cloud Run 或 App Engine 等部署到专用实例上。.

因此,我们必须

  • 创建 Dockerfile

  • 构建我们的应用程序映像

  • 在注册表中存储图像

让我们从创建 Dockerfile 开始。如前所述,这包括用于创建 Docker 镜像的一系列命令。就 Streamlit 应用程序而言,Dockerfile 可分为几个区块:

  • 定义运行环境:在我们的例子中为 python 3.7

  • 定义运行应用程序的端口

  • 使用 requirements.txt 文件安装所需的库及其依赖项

  • 复制应用程序的代码,并定义启动应用程序的工作目录

  • 定义运行应用程序的命令

├── app.py <- 启动 Streamlit 应用程序的主脚本
├── text_explorer <- 收集所有功能和代码的文件夹
├── requirements.txt <- 列出安装所需库的文件
└──参考资料 <- 包含徽标和图像的文件夹

有了这种结构,下面是我们为应用程序使用的 Dockerfile 的示例:

从 python:3.7

# 显示您希望应用程序使用的端口
公开 8080

# 升级管道和安装要求
复制 requirements.txt requirements.txt
运行 pip install -U pip
运行 pip install -r requirements.txt

# 复制应用程序代码并设置工作目录
COPY text_explorer text_explorer
COPY app.py app.py
复制参考文献 参考文献
工作目录 .

# 运行
ENTRYPOINT [“streamlit”、“run”、“app.py”、“-server.port=8080”、“-server.address=0.0.0.0”]

一旦创建了 Dockerfile,我们就可以按照 GCP 友好的命名约定构建我们的镜像,这将有助于稍后的部署。这可以通过以下命令完成:

docker build -t eu.gcr.io/gcp_project_name/app_name:v1 .

若要根据自己的应用程序进行调整,请将‘......‘gcp_project_name’ 您自己的 GCP 项目名称和‘......"。‘app_name’ 的版本号。您还可以通过修改‘...... "来更新版本号。‘v1’后缀的当前版本。.

将应用程序打包成 docker 镜像后,我们就可以将其部署到 GCP 上,让我们的队友也能访问它。.

使用 Cloud Run 部署应用程序

Cloud Run 是一种 GCP 无服务器 cloud 服务,用于轻松部署预构建的应用程序。它的主要优势之一是能自动完成大部分资源管理流程。因此,您只需告诉 Cloud Run 您的 Docker 映像在哪里,Cloud Run 就会将其部署到无服务器环境中,而无需指定最佳资源数量等。.

为此,您可以按照以下步骤操作:

  • 初始化 gcloud 右侧 GCP 项目上的模块:

gcloud 启动

  • 使用以下命令将 docker 推送到 GCP 容器注册中心:
docker push eu.gcr.io/gcp_project_name/app_name:v1
  1. 进入 GCP 项目的云运行部分。点击 “创建服务”,选择区域并定义服务名称。然后,选择与你的 Streamlit 应用程序相对应的 Docker 映像,并用你在 Dockerfile 中定义的端口更新端口

云运行界面

  • 最后,您可以按照链接到新创建的云运行服务的 URL 测试您的应用程序

正如您所看到的,部署只需几步即可完成,即使对于应用程序部署新手来说也非常简单。然而,在我们的案例中,除了部署之外,我们还希望确保应用程序的安全,使其只能在公司内部访问,而当时我们没有找到任何适合 Cloud Run 的 “简单 ”解决方案。这就是为什么我们决定寻找一个替代解决方案,让我们能够在没有太多困难的情况下拥有这个安全层,最终我们选择了 App Engine。.

使用应用引擎部署应用程序

App Engine 是一种基于 cloud 的计算服务,用于托管谷歌基础架构中的网络应用程序。简而言之,它允许你做与 Cloud Run 相同的事情,因为它们都是允许你部署应用程序的谷歌 cloud 服务。不过,与 Cloud Run 不同的是,Cloud Run 只为收到的请求付费,而 App Engine 则为整个运行时间付费,无论是否有请求。因此,最终来说,App Engine 可能是一个更昂贵的解决方案。尽管如此,我们还是决定采用这种解决方案,因为 App Engine 的优势在于与 IAP(身份感知代理)的原生集成,可以轻松确保应用程序的安全。.

在 App Engine 上实现部署的步骤并不比 Cloud Run 多,也不复杂,以下是您需要做的事情:

  • 检查文档文件中指定的端口,必须是 8080,以便与应用程序引擎兼容
  • 使用以下命令在右侧 GCP 项目中初始化 gcloud 模块:
gcloud 启动
  • 在项目根目录下(即与主脚本和 Dockerfile 处于同一级别)为应用程序创建一个 YAML 文件(名为 app.yaml),模板如下:

app.yaml file exampleapp.yaml 文件示例

用自己的应用程序服务名称更新服务名称

在这里,我们定义了 runtime: custom 选项,因为自定义运行时可以让你构建的应用程序在 Dockerfile 所定义的环境中运行,我们就是这种情况。env:flex 选项意味着我们的应用程序将在灵活环境中运行(与标准环境相反)。之所以做出这样的选择,是因为灵活环境是在谷歌计算引擎虚拟机(VM)上的 Docker 容器中运行应用程序,其限制比标准环境少(例如,应用程序不能写入磁盘)。有关主要区别的更多详情,请参阅 Google 文档。.

您还可以在 YAML 文件中包含更详细的网络、资源和扩展设置,例如为服务提供的最小实例数或 CPU 数量。您还可以在该文件中定义一些环境变量,以便应用程序可以访问它们。.

  • 运行以下命令(可能需要几分钟):
gcloud 应用程序部署 app.yaml
  • 使用部署命令完成后,应用程序就可以在 App Engine 上运行,您可以直接在 GCP 上找到它的专用 URL

如果您想确保应用程序的安全,并限制某些人的访问权限,请进入 GCP 项目的 “IAM 与管理”/“身份感知代理 ”部分:

  • 在 “所有网络服务 ”中,你应该能看到 “应用引擎应用程序 ”部分。如果 IAP 已关闭,请将其打开,然后点击 Streamlit 服务。.

管理权限的 IAP 部分

  • 在右侧点击 “添加成员”,输入您想要的所有电子邮件地址(或链接到邮件列表的别名),然后选择 “IAP-安全 Web 应用程序用户 ”角色。.

然后就大功告成了。现在,您的应用程序已经部署完成,并且安全可靠。.

在部署的应用程序中显示图像时遇到困难的提示

使用 st.pyplot() 或 st.image() 时,在查看部署的应用程序时可能会遇到一些显示问题(例如,显示的是 “0”,而不是绘图或图像)。我们建议尽可能使用 st.plotly_chart() 来避免这种情况,否则就使用 HTML 代码片段。例如,在我们的例子中,我们想显示一些 wordclouds,但这无法通过 Plotly 来实现。因此,我们决定将 wordcloud 图像以 PNG 格式保存在专用的 GCS 文件桶中,然后以字节形式下载,并用一些 HTML 代码显示出来,如下所示:

def display_wordcloud(image):
st.markdown(
f"""

""",
unsafe_allow_html=True
)
st.markdown("")
st.markdown("")

在该示例中,变量 “image ”是一个字节对象,来自 Google cloud 存储 python 软件包的 .dowload_as_bytes() 方法。.

结论

本文的目的是为您提供一些可用于部署 Streamlit 应用程序的 cloud 服务的提示和示例。根据我们的经验,如果您需要一个安全层来确保限制某些人的访问,那么 App Engine 将是合适的解决方案。否则,Cloud Run 仍然是部署 Streamlit 应用程序的简便方法。.

荣誉Paul Devienne、Amale El Hamri