部署streamlit app到Azure (Docker 入门篇)

文章目录

前言

三个步骤 

一、本地运行Streamlit

二、Docker 包装

Dockerfile

environment.yml

run.sh

建立镜像

三、部署到Azure云

deployment.yml

nginx.conf

run.sh

Dockerfile

总结

Reference


前言

怎么说呢,为了让简历更加吸引人,博主不得不踏上了Azure, Docker的学习路程,开始为自己原来课上做的project部署一个streamlit app网站。project沿用了教授随便起的名字-musical_robot, 可以帮助用户判断一段音乐属于什么类别(hiphop, rap...)。 整个网站是用streamlit 搭建的,但是只能在自己电脑上localhost运行。博主便想把它部署在Azure上,这样远程就能访问啦。

首先,这个原project用到了机械学习方面的内容,需要下载很多的音乐片段,这些片段用librosa分析成乐谱spectrogram后,被分类并保存。所以原porject需要包含这些音乐片段,大概有8000个30秒的片段,7.5GB大小。没部署前,用户使用这个project的条件之一就是先下载7个多G的音乐 :( 不是很理想对吧?所以作者想了办法把它部署在云平台上,这样一来用户电脑手机随时都可以使用这个project。

好了,让我们见证一下菜鸡博主如何做到streamlit云部署的吧。


三个步骤 

 这篇文章帮助新手快速用Docker将streamlit app包装,包装后上传到Azure云服务器上,形成一个托管的网站。 部署的网站是azurecontainer.io的域名,用户也可以之后自行购买自定义的网站域。最后的网站demo如下:

部署streamlit app到Azure (Docker 入门篇)_第1张图片

那么,简单将这一系列操作分为三个步骤:本地运行streamlit, docker 包装,部署到Azure。有耐心的同学往下看叭,希望能有帮助。 


一、本地运行Streamlit

 稍微介绍一下我的project目录树,看起来是这样的:

部署streamlit app到Azure (Docker 入门篇)_第2张图片

最上面的目录是musical_robots, 和它平行的最外层,是很重要的之后会用到的Dockerfile, deployment.yml等等...

musical_robots 之下是Tests, __pycache__(这个本来应该删掉的...),和data。

demo.py 包含的是用streamlit框架写的网站主体,spectrogram_dataset.py, svm_prediction.py, 还有dataset_queries.py 都是一些机器学习和提取数据的方程。机智的你也许发现了,还有个Justin-Bieber的歌曲《Stay》哈哈哈,是用来demo展示的。

注意的是,这里的streamlit写框架时,你的工作目录需要是和Dockerfile, musical_robots文件夹平行的,根目录这里。需要使用相对路径,而不是绝对路径。因为我们要把streamlit的app上传到网络上,每次这个app在借助云服务器运行时,用的路径是一样的,确定的,而不是你自己电脑上的。这里建议在写框架时用 os.path(),os.getcwd() 方法。注意这些,之后就不会被路径错误的问题困扰啦。


二、Docker 包装

还没有安装Docker的用户,可以官网安装一波。作者使用的是Windows系统,平常也经常使用WSL2, 安装Docker for Windows将自动帮助你连接WSL2,同时也可以在Windows客户端直接操作,非常好用。

这一步的重点是学习如何编辑Dockerfile, envrionment.yml。Dockerfile是告诉Docker如何将你的应用包装的重要文件,enviroment.yml 告诉机器需要安装的方法library, package, 等应用包裹。

Dockerfile

首先打开Ubuntu terminal, 在project的根目录创建Dockerfile。之后的所有文件都是在此目录创建的。打开Dockerfile, 输入以下指令。 

(新手用户只需要把 line 3,4,5里的root_dir改为自己的根目录名称,line 11的app_dir改为app的文件夹, 我的是musical_robots,其他不变就好啦)

部署streamlit app到Azure (Docker 入门篇)_第3张图片

  • mambaorg/micromamba是Docker Hub 提供的一个镜像模板,可以快速地帮助用户建立一个编程环境和镜像。FROM 是告诉Docker引用这个镜像.
  • 2-5 行使用 USER root 来告诉机器创建project的根目录,并作为工作的目录。注意,建立镜像其实一部分就是copy paste,把自己的目录,文件,编程应用包通通复制粘贴到新的环境里,最后再包装为新的镜像的过程。
  • 6-11 告诉机器采用micromamba 环境,复制environment.yml 并安装environment里的应用包到新环境里,再把所需的streamlit代码和run.sh复制下来。
  • 12-14 告诉机器切换回root环境,使用 chmod a+x run.sh来将run.sh对所有人可执行化。最后执行run.sh。

environment.yml

同样地,创建一个envrionment.yml. 用来告诉机器,需要安装哪些包裹,才能运行你的streamlit app。对于它,我觉得不用细说直接下一个吧。

部署streamlit app到Azure (Docker 入门篇)_第4张图片

run.sh

再接着,最后一个run.sh,如下图。

部署streamlit app到Azure (Docker 入门篇)_第5张图片

这个文件呢,就是告诉机器怎样才能运行你的streamlit app。注意,我们现在的工作路径是根目录,运行demo是在下面的musical_robots里。后面的 theme dark 是为了网站看起来更酷炫黑一点哈哈哈。

建立镜像

好了,剩下的就是返回terminal, 开始用Docker包装了。还是在根目录root_dir里,在terminal中输入:

docker build -t project_name:v1 . --no-cache=true

docker run --m -p 8880:8501 project_name:v1 

 第一行告诉docker读取当前目录的Dockerfile, 并创建一个project_name的镜像,贴上v1的tag标签,不使用cache。 这时候docker就会一行一行执行刚才Dockerfile的命令了。micromamba的图标也会显示,正在安装你所要求的包裹。 

耐心等待后镜像就安装完成了。这时可以通过docker images显示已有的镜像。

第二行告诉docker运行刚才的镜像,并把输出的port 8880 对应在port 8501上 (如果你用过streamlit,你知道port 8501是streamlit的网站接口)。这样一来打开浏览器的 localhost:8880 就是streamlit的网站了。-rm -p 告诉docker在运行镜像的同时,看它何时停止运行,停止运行后就删除掉。没有任何问题的话,到这里我们成功地建立地docker镜像了,也就是完成了第二步。

三、部署到Azure云

接下来是最后的环节了,部署到微软Azure上。首先需要创建一个Azure账户,作者用的学生账户,可以享受一年免费的特定服务,并且给了100的额度。这100可以用来作我们容器运行的经费hhh,毕竟作者刚部署两天就花了2多?

Ok. 下一步,在terminal下载azure 的cli。先试下以下command line:

az login

如果没有安装的话,会提示你安装,就下载最新版本好了。安装的话,会提示你 输入上面的网站,和code,再登陆到你的Azure账户,就可以返回terminal了。这时我们成功在terminal上登陆到Azure Command Line Interface,用来操控Azure云端。

下一步我们先需要一个Azure的resource group,这个resource group可以很容易在Azure网页端创建,作者自己本来就有一个resource group,所以直接讲之后的吧。

确保自己有了一个resource group, 名字的话假设是res_group. 在terminal输入:

az acr create --resource-group res_group --name name_of_registry --sku Basic

 这个name_of_registry将会是你自己设置的注册表名称.

az acr login -n name_of_registry

登录到注册表,成功的话会提示一个Login Succed. 然后更改一下Azure端的权限,并记住密码credential, 也就是输出的第一个password。

az acr update -n name_of_registry --admin-enabled true
az acr credential show --name name_of_registry

到这里,Azure端就准备就绪了。回到Docker,还需要创建2个用来部署的文件,分别是deployment.yml 和 nginx.conf。同时,Dockerfile和run.sh也需要改动一下,最后重新建立一次镜像。当然,你可以直接一次性把需要的文件都写好,再建立镜像。不过第二步的作用,主要是为了让新手能熟悉操作Docker,了解它是如何包装的,这样以后无论是Azure还是其他别的云平台,都能部署地更上手。

deployment.yml

还在根目录中,创建deployment.yml。deployment.yml用来告诉Azure如何部署你的Streamlit app。 新手需要改动的地方是

  • line 2 location: Some_location, 也就是服务器地区,作者在阿迈利卡,换成 westus 或者 eastus
  • line 3 是一个container instance name,也就是容器实例名称,自己随便取
  • line 6 是一个container name, 也就是容器名称,自己随便取
  • line 8,9,20 是name_of_registry,之前的注册表名字
  • line 21 输入我们之前保存的密码 credential
  • line 30 Some_dnsName 是一个自定义的域名,可以是你喜欢的任何名字,之后的网站也会用这个名字. 网站全称会是 Some_dnsName.Some_location.azurecontainer.io

部署streamlit app到Azure (Docker 入门篇)_第6张图片

nginx.conf

 nginx.conf 是针对网络接口和reroute管理的。没有nginx,我们的网站需要用户浏览器输入Some_dnsName.Some_location.azurecontainer.io:8501 才能打开。那么具体是怎么操作请看下面。新手需要改动的地方只有 line 22,53 的Some_dnsName, Some_location。nginx告诉机器获取port 80 (默认接口) 到 port 8501 (streamlit的接口)。 下面的location /statics, location /healthz等都是streamlit运行不可或缺的。作者这里还在line 20改动了以下,把client_max_body_size 改到了 8m. 意思是说,用户在网页上传的文件大小提高到8MB,而默认只有1MB,肯定不够上传音乐文件的。。作者在这里搞了很久才明白过来,不然一到上传文件的时候,网页就报错status code 401。

部署streamlit app到Azure (Docker 入门篇)_第7张图片

run.sh

 为了让nginx.conf在需要的时候运行,我们需要把它加入到run.sh里。只需要添加两行,改成这样:

部署streamlit app到Azure (Docker 入门篇)_第8张图片

 Dockerfile

最后,又回到我们创建的第一个文件Dockerfile. 因为我们新创建了deployment.yml 和nignx.conf,我们要添加命令把nginx.conf考虑进去。deployment.yml 没有出现在Dockerfile,是因为它是针对Azure的部署文件,和我们的包装没有关系。同样的,新手只需要按照下面这个格式写就完成了。 

部署streamlit app到Azure (Docker 入门篇)_第9张图片

 到这里,我们不需要再改动任何文件了。万事俱备只欠东风。再确认下,我们根目录下有app_dir, deployment.yml, environment.yml, Dockerfile, nginx.conf, 和run.sh 这6个。

重新docker build, 将花费一点时间。

docker build -t project_name:v1 . --no-cache=true

除了这个tag,我们还需要在前面加上另一个Azure registry注册表的tag. 之后把镜像push推送到Azure云端,输入:

docker tag project_name:v1 name_of_registry.azurecr.io/project_name:v1

docker push name_of_registry.azurecr.io/project_name:v1

 最后的最后,部署这个镜像产生新的容器实例, 运行:

az container create --resource-group res_group --name Some_name -f deployment.yml

注意,--name 后面的是Some_name,也就是deployment.ym里第3行的name,是我们的容器实例名称。等待一会儿完成后,我们上到Azure 客户端查看。 

部署streamlit app到Azure (Docker 入门篇)_第10张图片

部署完成!复制显示的FQDN, 输入浏览器,就可以远程访问啦,无论手机电脑都ok的。

撒花✨

总结

总体来说,Docker的包装,以及Azure的部署,对新手需要的操作性很友好。但即使这样,作者还是踩了不少坑,花了大量的时间在docker build, azure container deploy上。原因一是,我的工作目录一直在根目录上,运行streamlit app 需要继续保持在根目录上,不然会找不到streamlit command (没有添加export path),而我的代码原来默认工作目录在app_dir上,所以需要一定的改动才能运行。原因二是,我的网站要用户上传音乐文件,大部分超过nginx默认的1MB,所以不停报错status coed 401. 一系列分析后,我把client_max_body_size 改动到8m, 重新docker build再上传。还是不断报错,以为是其他地方出错,试了很久也不对。最终我把保存的镜像删除了,本地还有Azure端都删除,只改动了client_max_body_size,还是改动到8m。 这样重新docker build, azure deploy,才成功。好像是nginx.conf再重新建立镜像覆盖到已有的镜像时,改动并没有更新,和原来的镜像一模一样。。我不李姐。。原因三,各种Some_name, another_name, name_of_registry等等很多,作者一开始小白完全不了解每个名字背后的含义,看了别人的教程,可惜教程里这一块没有详细的讲解,导致我的命名有些混乱,好在我没有出错,并没有耗费时间。 对于新手,把名字的含义,还有各行Dockerfile等文件的代码摸清楚大概,虽然不是必须要求,但对于你了解流程有天地差别的帮助。

好啦,希望各位友友看了作者的笔记后,能够快速清晰地将streamlit app部署到Azure上啦。以下是作者觉得很有帮助的reference.

Reference

Beginner Guide to Streamlit Deployment on Azure | by Sergei Issaev | Jan, 2022 | Towards Data Science

Buy a custom domain name - Azure App Service | Microsoft Docs  购买自定义域名, 好像是11.99美元一年.

Micromamba — documentation micromamba 镜像

你可能感兴趣的:(azure,docker,python,容器,nginx)