Streamlit:使用Docker在云服务器上部署Streamlit并绑定域名
首先来看最终效果:
- http://www. domain.com (在绑定域名,并完成了docker部署和端口映射后,可以通过你绑定的域名访问Streamlit)
- http:// 101.34.23.XXX (没有绑定域名,但完成了docker部署和端口映射,可以直接通过你的云服务器的公网IP访问Streamlit而无需端口号)
- http:// 101.34.23.XXX:8501 (没有绑定域名,没有使用docker部署,直接在服务器上终端运行streamlit run,可以直接通过你的云服务器的公网IP+端口号访问Streamlit)
- 点击以上任意一个IP地址或URL,可以访问你搭建好的Streamlit网页(不用真的点,我瞎写的,举个例子):
为了实现这种效果,本文和引用文章会展示以下几个重点:
- 如何连接到购买一台/使用自己的云服务器,将本机中写好的Streamlit脚本及资源文件传输到服务器并运行,以实现 效果3
- 如何安装并使用docker,在服务器内创建streamlit镜像并部署,通过docker的端口映射实现 效果2
- 如何在 2 的基础上,购买/绑定一个你拥有的域名,解析到服务器的IP地址,实现 效果1
一、购买云服务器(已有可跳过)
感谢 @jackiexiao 的教程,建议学习此教程的前半部分了解如何选购一台云服务器:
二、在服务器端部署Streamlit(实现IP+端口访问)
你已经拥有了一台云服务器,在拿到公网IP后,就可以在本机使用ssh远程连接你的服务器对它进行操作了
1. 通过SSH和SFTP连接服务器
找一个ssh客户端(xshell/vscode),如果你是Mac系统,也可以和我一样直接使用终端(Terminal)
ssh ubuntu@yourIP
通过SSH连接,你就可以输入任何指令操作你的服务器了。 以后的所有操作指令(除了上传文件)都将通过SSH连接的终端进行。
接下来,我们需要将在本机写好的python项目上传至服务器中。为此需要让本机和服务器建立sftp连接
再打开一个终端,输入以下命令。和ssh连接相同。只是换成了sftp。同样,如果你使用了密钥,无需输入密码,否则需要输入密码。 这里的ubuntu可以换成云服务器提供给你的登录名,@后面的yourIP需要替换成你的云服务器的公网IP
sftp ubuntu@yourIP
sftp连接成功后,你就可以使用put命令将本地的python项目上传至服务器了
put [-E] [-a] [-c] [-O base] lfile [-o rfile]
但是,如果你不想逐个上传文件,而是想直接上传整个python项目文件夹,首先需要在服务器端建立一个同名的文件夹,才能上传
2. 传输整个python项目目录到服务器
使用的目录是含有一个资源文件,一个python脚本的简单示例。可以在此处下载: my_st.zip
这里最好回到建立了ssh连接的终端,而不是在sftp终端里继续操作。
创建与本地项目文件夹同名的目录:
cd && mkdir my_st
创建好后,你可以用tree命令查看当前系统内的文件结构:
cd && tree
可以看到已经出现了空的文件夹my_st:
ubuntu@VM-0-11-ubuntu : ~ $ cd && tree
.
├── get-docker.sh
└── my_st
1 directory, 1 file
接下来回到sftp终端,使用put命令上传整个项目文件夹。因为已经在服务器根目录建好了同名文件夹,这里无需再写输出目录,直接:
put -r /Users/MyUserName/Documents/my_st
再次使用tree命令查看当前系统内的文件结构,可以看到已经成功上传了整个文件夹:
ubuntu@VM-0-11-ubuntu : ~ $ cd && tree
.
├── get-docker.sh
└── my_st
├── test.py
└── url
└── url.txt
2 directories, 3 files
3. 在服务器端安装Python和其他Python库
至此,你只需要在服务器里安装python和pip install streamlit,即可在服务器终端运行streamlit。由于大部分云服务器自带python,所以可以在终端中输入python并回车,查看当前的python版本:
ubuntu@VM-0-11-ubuntu : ~ $ python
Python 3.8.10 (default, Sep 28 2021, 16:10:42)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> exit()
ubuntu@VM-0-11-ubuntu : ~ $
如上,我的python版本是3.8,不要忘记输入exit()退出python
那么接下来你只需要pip安装streamlit(或其他你需要的包):
pip install streamlit
4. 运行Streamlit,发布页面
安装完成后,进入python项目目录,使用streamlit run,即可成功发布streamlit网页:
cd my_st && nohup streamlit run test.py
至此,效果3已经实现了。你可以通过访问服务器的公网IP+Streamlit占用的端口号的方式访问你的Streamlit网页,并分享给其他人。
注意,这里带上nohup意味着服务器会在后台运行streamlit,控制台输出到nohup的output文件中。关闭终端或Ctrl+C都不能结束进程。
如果你想关闭它,请参考这里: nohup和&后台运行,进程查看及终止
如果你想要的不止于此,又或者你有一个自己的域名,希望别人可以通过域名访问你的Streamlit页面,可以继续往下了解如何实现将Streamlit占用的端口映射到服务器的80端口(通过http访问),以及绑定域名。
三、使用Docker重新部署Streamlit项目以实现Docker的端口映射
我们都知道,Streamlit是不能设置端口为80端口的。因为它被服务器默认用来做http访问。如果你希望只需要输入公网IP就可以访问Streamlit页面,或者是输入域名访问,就需要将Streamlit的端口映射到80端口。
端口映射的方法有很多,最有效的方式是 反向代理 ,通常使用Nginx实现。但由于笔者技术有限,没能成功配置Nginx配置文件实现反向代理(),所以选择了另一种方式:Docker端口映射。
1. 什么是Docker
首先需要了解一下什么是Docker:
Docker 是什么
Docker 是一个应用打包、分发、部署的工具
你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,
而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。
—— Docker 简介和安装 - Docker 快速入门
也就是说,我们只需要将Streamlit项目制作成Docker镜像,再运行镜像生成一个可以自动运行Streamlit的容器,将容器的端口号(也就是Streamlit的)映射到服务器的80端口,即可实现。
Docker的优势还有很多,笔者仅仅是用到了一个很小的功能。
2. 安装Docker
# 如果当前不是root用户,需要 sudo su 切换至root用户执行以下命令
apt update # 必须先update,才能安装软件
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun # mirror是镜像,为了加速
# 如果出现报错,一般是无法链接到get.docker.com的问题,可以使用国内镜像一键安装代替:
# curl -sSL https://get.daocloud.io/docker | sh
可能需要等待一段较长的时间直至docker安装完成
安装完成后我们输入exit切换回自己的用户,如ubuntu。最好不要在root用户下进行后续操作,减少无谓的黄字报错
exit
3. 创建Docker镜像
接下来准备创建docker镜像。 在服务器的python项目外,也就是根目录中 创建一个目录docker_file,并且在其中创建一个文件Dockerfile,进入vim编辑模式开始编写它
cd && mkdir docker_file && touch docker_file/Dockerfile && vim Dockerfile
将以下内容粘贴到Dockerfile内,在英文输入法下输入:wq(冒号也要输入)并按下回车,以保存Dockerfile的修改
# 从python3.9镜像基础上创建
FROM python:3.9
# 设置镜像源,提高pip install 速度。如果你有多个包需要安装,建议使用requirements.txt形式
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ \
&& pip install streamlit