新手程序员面临的困难的问题之一是理解“环境”的概念。环境就是你编写代码的系统,听起来很容易,但很快你就会明白维护系统有多困难。

创新互联公司一直通过网站建设和网站营销帮助企业获得更多客户资源。 以"深度挖掘,量身打造,注重实效"的一站式服务,以成都网站设计、成都做网站、移动互联产品、全网整合营销推广服务为核心业务。10余年网站制作的经验,使用新网站建设技术,全新开发出的标准网站,不但价格便宜而且实用、灵活,特别适合中小公司网站制作。网站管理系统简单易用,维护方便,您可以完全操作网站资料,是中小公司快速网站建设的选择。
很大原因是库和 IDE,甚至 Python 代码本身都会经历更新和版本更改,有时候,我们对一个库进行更新,就会导致另一段代码报错。正因如此,我们经常需要修复各种来源不明的 BUG。
此外,如果我们同时开发多个项目,可能会出现依赖性冲突。如果一段代码因为另一段代码而出现 BUG 时,情况会更糟糕。
另外,如果你想将一个项目共享给一个在不同操作系统上工作的团队成员,或者将你在 Mac 上构建的项目发送到另一个操作系统上的服务器,你是否需要重新配置代码?很明显是一定需要的。
因此,为了减少这些问题的出现,人们提出使用容器来分离项目和它们所在的环境。容器基本上是一个环境可以运行的地方,与系统中的所有其他东西分开。一旦定义了容器中的内容,就可以轻松地重新创建环境,甚至与同事共享项目。
要求
首先,我们需要安装一些设置:
Windows或macOS:安装Docker Desktop(https://www.docker.com/get-started)
Linux:先安装Docker,再安装 Docker Compose(https://docs.docker.com/compose/install/)
对Python服务进行容器化
假设我们正在创建一个名为 server.py 的 Flask 服务,并假设文件内容如下:
- from flask import Flask
 - server = Flask(__name__)
 - @server.route("/")
 - def hello():
 - return "Hello World!"
 - if __name__ == "__main__":
 - server.run(host='0.0.0.0')
 
如上所述,我们需要记录代码的依赖关系,因此,我们可以创建一个 requirements.txt 文件,其中可以包含以下要求:
- Flask==1.1.1
 
因此,我们的软件包需要具有以下结构:
- app
 - ├─── requirements.txt
 - └─── src
 - └─── server.py
 
该结构非常合理(源代码保存在单独的目录中)。要执行我们的 Python 程序,只需安装一个Python 解释器并运行即可。
我们可以在本地运行该程序,但是假设我们正在处理 15 个项目:在容器中运行是有意义的,这样可以避免与其他项目发生冲突。
让我们进入容器化。
Dockerfile
要运行 Python 代码,我们将容器打包为 Docker 映像,然后基于它运行一个容器。如下所示:
分析 Dockerfile
Dockerfile 是一个文件,其中包含有关组装 Docker 映像(保存为 myimage )的说明:
- # 设置基本映像(主机操作系统)
 - FROM python:3.8
 - # 在容器中设置工作目录
 - WORKDIR /code
 - # 将依赖项文件复制到工作目录中
 - COPY requirements.txt .
 - # 安装依赖项
 - RUN pip install -r requirements.txt
 - # 将本地src目录的内容复制到工作目录
 - COPY src/ .
 - # 在容器启动时运行的命令
 - CMD [ "python", "./server.py" ]
 
Dockerfile 是逐行编译的,因此构建器会生成图像层并将其堆叠在先前的图像上。
我们还可以在 build 命令的输出中观察到作为步骤执行的 Dockerfile 指令。
- $ docker build -t myimage .
 - Sending build context to Docker daemon 6.144kB
 - Step 1/6 : FROM python:3.8
 - 3.8.3-alpine: Pulling from library/python
 - …
 - Status: Downloaded newer image for python:3.8.3-alpine
 - ---> 8ecf5a48c789
 - Step 2/6 : WORKDIR /code
 - ---> Running in 9313cd5d834d
 - Removing intermediate container 9313cd5d834d
 - ---> c852f099c2f9
 - Step 3/6 : COPY requirements.txt .
 - ---> 2c375052ccd6
 - Step 4/6 : RUN pip install -r requirements.txt
 - ---> Running in 3ee13f767d05
 - …
 - Removing intermediate container 3ee13f767d05
 - ---> 8dd7f46dddf0
 - Step 5/6 : COPY ./src .
 - ---> 6ab2d97e4aa1
 - Step 6/6 : CMD python server.py
 - ---> Running in fbbbb21349be
 - Removing intermediate container fbbbb21349be
 - ---> 27084556702b
 - Successfully built 70a92e92f3b5
 - Successfully tagged myimage:latest
 
然后,我们可以看到映像位于本地映像存储目录中:
- $ docker images
 - REPOSITORY TAG IMAGE ID CREATED SIZE
 - myimage latest 70a92e92f3b5 8 seconds ago 991MB
 
在开发过程中,我们希望花费尽可能少的时间,为 Python 服务重建映像。
注意:Docker 和 virtualenv 非常相似但又有所不同。Virtualenv 只允许我们在 Python 的依赖关系之间切换,无法使用主机操作系统。但是,使用Docker,你可以在任何操作系统上交换整个操作系统:安装并运行Python(例如 UBTUN,Debian,Alpine,甚至Windows Server Core)。因此,如果你的团队工作需要验证你的技术,请使用Docker。如果不需要,可以使用 venv。
总结
在上文中,我们展示了如何把 Python 服务容器化。 希望此过程将变得更容易,并且能够为你的项目提供更长的保质期。同时,因为依赖关系的变化,也能降低你的代码错误的可能性。