Docker解释:如何容器化PythonWeb应用程序

来自菜鸟教程
跳转至:导航、​搜索

状态: 已弃用

本文已弃用,不再维护。

原因

本文中的技术已经过时,可能不再反映 Docker 的最佳实践。

请参阅


介绍


Web 应用程序被劫持并用于接管整个主机的威胁是巨大而可怕的。 长期以来,将事物彼此隔离以增强安全性一直是一项挑战,尤其是在应用程序属于不同客户端的情况下。 可以采取许多措施来防止这种不幸的情况发生,但是对于大多数开发人员或管理员的用例而言,它们通常成本太高(时间和资源)或太复杂。

在这篇 DigitalOcean 文章中,我们将讨论“容器化”Python Web 应用程序,以便将它们放在非常安全的沙箱中,绝对保存在它们自己的环境中(除非你明确地将它们“链接”到另一个环境)。 为了实现这一点,我们将逐步了解如何创建一个 docker 容器来托管 Python Web 应用程序,最后使用 Dockerfile 引导我们的构建过程以使其完全自动化。

词汇表


1. Docker 简介


2. 在 Ubuntu 上安装 Docker


3. 基本的 Docker 命令


  1. 运行 docker 守护进程和 CLI 用法
  2. 码头工人命令

4. 将 Docker 容器构建到沙箱 Python WSGI 应用程序


  1. 从 Ubuntu 创建基础 Docker 容器
  2. 为安装准备基本容器
  3. 安装用于部署的常用 Python 工具
  4. 安装 Web 应用程序及其依赖项
  5. 配置 Python WSGI 应用程序

5. 创建 Dockerfile 以自动构建镜像


  1. Dockerfile 基础
  2. Dockerfile 命令概述
  3. 创建 Dockerfile
  4. 定义基本面
  5. 更新安装的默认应用程序存储库
  6. 安装基本工具
  7. Python 和基本 Python 工具的基本安装说明
  8. 应用部署
  9. 引导一切
  10. 最终的 Dockerfile
  11. 使用 Dockerfile 自动构建容器

Docker 简介


docker 项目 提供了更高级别的工具,可以协同工作,这些工具构建在一些 Linux 内核特性之上。 目标是帮助开发人员和系统管理员移植应用程序——连同它们的所有依赖项——并让它们跨系统和机器运行——无头疼

Docker 通过创建安全的 LXC(即 Linux Containers) 基于应用程序的环境,称为 docker 容器 。 这些容器是使用 docker 镜像创建的,可以通过手动执行命令或通过 Dockerfiles 自动执行命令来构建。

注意: 了解更多关于 docker 及其部分(例如 docker daemon、CLI、图像等),请查看我们对项目的介绍性文章:docker Explained: Getting Started

在 Ubuntu 上安装 Docker(最新)


凭借其最新版本(0.7.1. 日期为 12 月 5 日),docker 可以部署在各种 Linux 操作系统上,包括 Ubuntu / Debian 和 CentOS / RHEL。

请记住,您可以使用 DigitalOcean 在 Ubuntu 13.04 上构建的即用型 docker 映像快速入门。

我们将快速介绍 Ubuntu(最新)的安装过程。

Ubuntu 安装说明


更新您的液滴:

sudo aptitude    update
sudo aptitude -y upgrade

确保 aufs 支持可用:

sudo aptitude install linux-image-extra-`uname -r`

将 docker 存储库密钥添加到 apt-key 以进行包验证:

sudo sh -c "wget -qO- https://get.docker.io/gpg | apt-key add -"

将 docker 存储库添加到 aptitude 源:

sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"

使用新增内容更新存储库:

sudo aptitude    update

最后,下载并安装docker:

sudo aptitude install lxc-docker

Ubuntu 的默认防火墙(UFW: Uncomplicated Firewall)默认拒绝所有转发流量,这是 docker 需要的。

使用 UFW 启用转发:

使用 nano 文本编辑器编辑 UFW 配置。

sudo nano /etc/default/ufw

向下滚动并找到以 DEFAULT_FORWARD_POLICY 开头的行。

代替:

DEFAULT_FORWARD_POLICY="DROP"

和:

DEFAULT_FORWARD_POLICY="ACCEPT"

CTRL+X 并用 Y 确认保存并关闭。

最后,重新加载 UFW:

sudo ufw reload

基本的 Docker 命令


在我们开始使用 docker 之前,让我们快速回顾一下它的可用命令,以刷新我们的第一篇 Getting Started 文章中的记忆。

运行 docker 守护进程和 CLI 用法


安装后,docker daemon 应该在后台运行,准备好接受 docker CLI 发送的命令。 对于可能需要手动运行 docker 的某些情况,请使用以下命令。

运行 docker 守护进程:

sudo docker -d &

码头工人 CLI 用法:

sudo docker [option] [command] [arguments]

注意: docker 需要 sudo 权限才能工作。

码头工人命令


以下是当前可用(版本 0.7.1)docker 命令的摘要:


附加到正在运行的容器

建造


从 Dockerfile 构建容器

犯罪


从容器的更改创建新图像

cp


将文件/文件夹从容器文件系统复制到主机路径

差异


检查容器文件系统上的更改

事件


从服务器获取实时事件

出口


将容器的内容作为 tar 存档流式传输

历史


显示图像的历史

图片


列出图像

进口


从 tarball 的内容创建新的文件系统映像

信息


显示系统范围的信息

插入


在图像中插入文件

检查


返回容器的底层信息


杀死一个正在运行的容器

加载


从 tar 存档加载图像

登录


注册或登录到 docker 注册服务器

日志


获取容器的日志

港口


查找经过 NAT 转换为 PRIVATE_PORT 的面向公众的端口

ps


列出容器


从 docker 注册表服务器中拉取图像或存储库


将图像或存储库推送到 docker 注册表服务器

重新开始


重新启动正在运行的容器

R M


移除一个或多个容器

rmi


移除一张或多张图片


在新容器中运行命令

节省


将图像保存到 tar 存档

搜索


在 docker 索引中搜索图像

开始


启动一个停止的容器

停止


停止正在运行的容器

标签


将图像标记到存储库中

最佳


查找容器的运行进程

版本


显示 docker 版本信息

将 Docker 容器构建到沙箱 Python WSGI 应用程序


在我们的 VPS 上安装了 docker 并快速查看了它的命令后,我们准备开始实际工作,创建运行 Python WSGI 应用程序的 docker 容器。

注意: 以下部分将使您能够拥有一个 dockerized(容器化)Python WSGI Web 应用程序。 但是,由于其复杂性和不实用性,绝对不是推荐的方法。 它在这里为您提供了一个学习如何使用实时容器并熟悉我们需要在下一节稍后定义的命令以自动化该过程的机会。

让我们开始!


从 Ubuntu 创建基础 Docker 容器


使用 docker 的 RUN 命令,我们将首先基于 Ubuntu 映像创建一个新容器。 我们将使用 -t 标志将终端附加到它,并将 bash 作为正在运行的进程。

我们将公开 端口 80 以便我们的应用程序可以从外部访问。 将来,您可能希望对多个实例进行负载平衡并将容器“链接”到彼此以使用反向代理运行容器访问它们。

sudo docker run -i -t -p 80:80 ubuntu /bin/bash

注意: 执行此命令后,docker 可能需要 pull Ubuntu 映像,然后才能为您创建新容器。

记住:您将被附加到您创建的容器中。 为了分离自己并返回主终端接入点,请运行转义序列:CTRL+P,然后是 CTRL+Q。 连接到 docker 容器就像连接到另一个内部的新液滴。

要将自己重新连接到此容器:

  1. 使用“sudo docker ps”列出所有正在运行的容器
  2. 找到它的 ID
  3. 使用“sudo docker attach [id]”附加回其终端

重要:请不要忘记,由于我们是一个容器,所以下面的所有命令都会在那里执行,不会影响它所在的主机。

为安装准备基本容器


为了在容器内部署 Python WSGI Web 应用程序 - 以及我们在该过程中需要的工具 - 相关的应用程序存储库必须可供下载。 不幸的是(并且故意保持简单)这是 而不是 与 docker 附带的默认 Ubuntu 映像的情况。

让我们将 Ubuntu 的 Universe 存储库附加到基础映像的默认应用程序源列表。

echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list

使用新添加的源更新列表。

apt-get update

在我们继续设置 Python WSGI 应用程序之前,我们应该拥有一些工具,例如 nano、tar、curl 等。 - 以防万一

让我们在我们的容器中下载一些有用的工具

apt-get install -y tar \
                   git \
                   curl \
                   nano \
                   wget \
                   dialog \
                   net-tools
                   build-essential

安装用于部署的常用 Python 工具


对于我们的教程(作为示例),我们将创建一个非常基本的 Flask 应用程序。 阅读本文后,您可以使用和部署您喜欢的框架,就像在虚拟服务器上部署它一样。

记住: 下面的所有命令和指令仍然发生在一个容器内,它几乎就像一个全新的水滴一样。

让我们从安装 Python 和 Python 包管理器 pip 开始我们的部署过程:

# Install pip's dependency: setuptools:
apt-get install -y python python-dev python-distribute python-pip

安装 Web 应用程序及其依赖项


在我们开始创建示例应用程序之前,我们最好确保所有内容 - 即 所有依赖项- 都在那里。 首先,您很可能将 Web 应用程序框架 (WAF) 作为应用程序的依赖项(即 烧瓶)。

由于我们已经安装了 pip 并准备好工作,我们可以使用它来提取所有依赖项并将它们设置在我们的容器中:

# Download and install Flask framework:
pip install flask

安装 pip 后,让我们在“my_application”文件夹中创建一个基本的示例 Flask 应用程序,该文件夹将包含所有内容。

# Make a my_application folder
mkdir my_application

# Enter the folder
cd my_application 

注意:如果您有兴趣部署您的应用程序而不是这个简单的示例示例,请参阅下面的“快速提示”中间部分。

让我们创建一个单页烧瓶“Hello World!” 使用纳米的应用程序。

# Create a sample (app.py) with nano:
nano app.py

并为我们刚刚提到的这个小应用程序复制并粘贴以下内容:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

按 CTRL+X 并用 Y 批准以保存并关闭。

或者,您可以使用“requirements.txt”来包含应用程序的依赖项,例如 Flask。

使用 nano 文本编辑器创建 requirements.txt:

nano requirements.txt

并在里面输入以下内容,以及所有依赖项:

flask
cherrypy

按 CTRL+X 并用 Y 批准以保存并关闭。

注意: 您可以使用 pip 创建实际应用程序依赖项的列表。 要了解如何操作,请查看我们的教程 常用 Python 工具:使用 virtualenv、使用 Pip 安装和管理包

我们最终的应用程序文件夹结构:

/my_application
    |
    |- requirements.txt  # File containing list of dependencies
    |- /app              # Application module (which should have your app)
    |- app.py            # WSGI file containing the "app" callable
    |- server.py         # Optional: To run the app servers (CherryPy)

注意:请参阅以下有关“server.py”的部分 - 配置您的Python WSGI应用程序

记住:这个应用程序文件夹将在容器内创建。 当您自动构建映像时(请参阅以下有关 Dockerfile 的部分),您需要确保在主机上具有此结构以及 Dockerfile。

__ * 实际部署的快速提示 * __

如何在容器中获取应用程序存储库及其要求


在上面的示例中,我们在容器内创建了应用程序目录。 但是,您不会这样做来部署您的应用程序。 您很可能从存储库中提取其源代码。

有几种方法可以将您的存储库复制到容器中。

下面解释其中的两个:

# Example [1]
# Download the application using git:
# Usage: git clone [application repository URL]
# Example:
git clone https://github.com/mitsuhiko/flask/tree/master/examples/flaskr

# Example [2]
# Download the application tarball:
# Usage: wget [application repository tarball URL]
# Example: (make sure to use an actual, working URL)
wget http://www.github.com/example_usr/application/tarball/v.v.x

# Expand the tarball and extract its contents:
# Usage: tar vxzf [tarball filename .tar (.gz)]
# Example: (make sure to use an actual, working URL)
tar vxzf application.tar.gz

# Download and install your application dependencies with pip.
# Download the requirements.txt (pip freeze output) and use pip to install them all:
# Usage: curl [URL for requirements.txt] | pip install -r -
# Example: (make sure to use an actual, working URL)
curl http://www.github.com/example_usr/application/requirements.txt | pip install -r -

配置 Python WSGI 应用程序


要为该应用程序提供服务,您将需要一个 Web 服务器。 为 WSGI 应用程序提供支持的 Web 服务器需要安装在与应用程序的其他资源相同的容器中。 实际上,它将是 docker 运行的进程。

注意: 在本例中,由于其简单性,我们将使用 CherryPy 内置的生产就绪 HTTP Web 服务器。 按照我们关于该主题的教程,您可以使用 Gunicorn、CherryPy 甚至 uWSGI(并在 Nginx 后面设置它们)。

使用 pip 下载并安装 CherryPy:

pip install cherrypy

创建一个“server.py”来为来自“app.py”的Web应用程序提供服务:

nano server.py

复制并粘贴下面的内容,以便服务器导入您的应用程序并开始提供服务:

# Import your application as:
# from app import application
# Example:

from app import app

# Import CherryPy
import cherrypy

if __name__ == '__main__':

    # Mount the application
    cherrypy.tree.graft(app, "/")
        
    # Unsubscribe the default server
    cherrypy.server.unsubscribe()

    # Instantiate a new server object
    server = cherrypy._cpserver.Server()
    
    # Configure the server object
    server.socket_host = "0.0.0.0"
    server.socket_port = 80
    server.thread_pool = 30
    
    # For SSL Support
    # server.ssl_module            = 'pyopenssl'
    # server.ssl_certificate       = 'ssl/certificate.crt'
    # server.ssl_private_key       = 'ssl/private.key'
    # server.ssl_certificate_chain = 'ssl/bundle.crt'
    
    # Subscribe this server
    server.subscribe()
    
    # Start the server engine (Option 1 *and* 2)
    
    cherrypy.engine.start()
    cherrypy.engine.block()

就是这样! 现在,您可以将“dockerized” Python Web 应用程序安全地保存在其沙箱中,只需运行以下命令即可为成千上万的客户端请求提供服务:

python server.py

这将在前台运行服务器。 如果要停止它,请按 CTRL+C。

要在后台运行服务器,请运行以下命令:

python server.py &

当您在后台运行应用程序时,您将需要使用进程管理器(例如 htop) 杀死(或停止)它。

注意: 要了解更多关于配置 Python WSGI 应用程序以使用 CherryPy 进行部署,请查看我们的教程:如何使用 CherryPy Web 服务器部署 Python WSGI 应用程序

为了测试一切运行顺利,他们应该考虑到所有端口分配都已经处理好了,您可以使用浏览器访问 http://[your droplet's IP] 以查看“[X206X ]Hello World!”消息。

创建 Dockerfile 以自动构建镜像


正如我们在上一步中提到的,对于可扩展的生产部署,当然不推荐以这种方式创建容器。 正确的做法可以认为是使用 Dockerfiles 以结构化的方式自动化构建过程。

在完成了在容器中下载和安装的必要命令之后,我们可以使用相同的知识来编写一个 Dockerfile,docker 可以使用它来构建一个镜像,然后可以使用它来轻松地运行 Python WSGI 应用程序容器。

在我们开始处理 Dockerfile 之前,让我们快速回顾一下基础知识。

Dockerfile 基础


Dockerfiles 是包含连续声明的命令的脚本,这些命令将由 docker 按该顺序执行以自动创建新的 docker 映像。 它们对部署有很大帮助。

这些文件总是以使用 FROM 命令定义基本映像开始。 从那里开始, 构建过程 开始,随后采取的每个操作都形成了将提交到主机上的最终映像。

用法:

# Build an image using the Dockerfile at current location
# Tag the final image with [name] (e.g. *nginx*)
# Example: sudo docker build -t [name] .
sudo docker build -t nginx_img . 

注意: 要了解有关 Dockerfile 的更多信息,请查看我们的文章:Docker 解释:使用 Dockerfiles 自动构建映像

Dockerfile 命令概述


添加


将文件从主机复制到容器中

命令


设置要执行的默认命令,或传递给 ENTRYPOINT

入口点


设置容器内的默认入口点应用程序

环境噪声


设置环境变量(例如 “键=值”)

暴露


将端口暴露在外面


设置要使用的基础镜像

维护者


设置 Dockerfile 的作者/所有者数据


运行命令并提交最终结果(容器)图像

用户


设置用户从镜像运行容器

体积


从宿主机挂载目录到容器

工作目录


设置要执行的CMD指令的目录

创建 Dockerfile


要使用 nano 文本编辑器在当前位置创建 Dockerfile,请执行以下命令:

sudo nano Dockerfile

注意: 将以下所有行一个接一个地附加以形成 Dockerfile。

定义基本面


让我们通过定义诸如 FROM 映像(即 Ubuntu)和维护者。

附加以下内容:

############################################################
# Dockerfile to build Python WSGI Application Containers
# Based on Ubuntu
############################################################

# Set the base image to Ubuntu
FROM ubuntu

# File Author / Maintainer
MAINTAINER Maintaner Name

更新安装的默认应用程序存储库


运行以下命令以使用其他应用程序更新 apt-get 存储库,就像我们在上一节中所做的那样。

附加以下内容:

# Add the application resources URL
RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list

# Update the sources list
RUN apt-get update

安装基本工具


更新默认应用程序存储库源列表后,我们可以通过获取我们需要的基本应用程序来开始我们的部署过程。

附加以下内容:

# Install basic applications
RUN apt-get install -y tar git curl nano wget dialog net-tools build-essential

注意: 虽然您不太可能需要上述某些工具,但我们仍然会得到它们 - 以防万一

Python 和基本 Python 工具的基本安装说明


为了部署 Python WSGI 应用程序,您极有可能需要一些我们之前使用过的工具(例如 )。 在继续设置框架之前让我们现在安装它们(即 您的 WAF) 和您选择的 Web 应用程序服务器 (WAS)。

附加以下内容:

# Install Python and Basic Python Tools
RUN apt-get install -y python python-dev python-distribute python-pip

应用部署


鉴于我们正在构建 docker 镜像来部署 Python Web 应用程序,我们都可以充分利用 docker 的 ADD 命令来复制应用程序存储库,最好使用 REQUIREMENTS 文件以一步快速运行。

注意: 要将所有内容打包在一个文件中而不是重复我们自己,一个类似于以下结构的应用程序文件夹可能是一个不错的方法。

示例应用程序文件夹结构:

/my_application
    |
    |- requirements.txt  # File containing list of dependencies
    |- /app              # Application module
    |- app.py            # WSGI file containing the "app" callable
    |- server.py         # Optional: To run the app servers (CherryPy)

注意:要了解如何创建这个结构,请回滚并参考安装Web应用程序及其依赖项部分。

附加以下内容:

# Copy the application folder inside the container
ADD /my_application /my_application

注意:如果要从在线主机git仓库部署,可以使用如下命令克隆:

RUN git clone [application repository URL]

请不要忘记将 URL 占位符替换为您的实际占位符。

引导一切


添加复制应用程序的说明后,让我们完成最终配置,例如从 requirements.txt 中提取依赖项。

# Get pip to download and install requirements:
RUN pip install -r /my_application/requirements.txt

# Expose ports
EXPOSE 80

# Set the default directory where CMD will execute
WORKDIR /my_application

# Set the default command to execute
# when creating a new container
# i.e. using CherryPy to serve the application
CMD python server.py

最终的 Dockerfile


最后,Dockerfile 应该是这样的:

############################################################
# Dockerfile to build Python WSGI Application Containers
# Based on Ubuntu
############################################################

# Set the base image to Ubuntu
FROM ubuntu

# File Author / Maintainer
MAINTAINER Maintaner Name

# Add the application resources URL
RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list

# Update the sources list
RUN apt-get update

# Install basic applications
RUN apt-get install -y tar git curl nano wget dialog net-tools build-essential

# Install Python and Basic Python Tools
RUN apt-get install -y python python-dev python-distribute python-pip

# Copy the application folder inside the container
ADD /my_application /my_application

# Get pip to download and install requirements:
RUN pip install -r /my_application/requirements.txt

# Expose ports
EXPOSE 80

# Set the default directory where CMD will execute
WORKDIR /my_application

# Set the default command to execute    
# when creating a new container
# i.e. using CherryPy to serve the application
CMD python server.py

再次按 CTRL+X 并用 Y 确认保存并退出文件。

使用 Dockerfile 自动构建容器


正如我们第一次在“基础”部分讨论的那样,Dockerfiles 的使用包括使用 docker build 命令调用它们。

由于我们正在指示 docker 复制一个应用程序文件夹(即 /my_application),我们需要确保在开始构建过程之前将它与这个 Dockerfile 放在一起。

这个 docker 镜像将允许我们使用单个命令快速创建运行 Python WSGI 应用程序的容器。

要开始使用它,请使用以下内容构建一个新的容器映像:

sudo docker build -t my_application_img . 

并使用该图像 - 我们标记为 my_application_img - 我们可以运行一个运行应用程序的新容器:

sudo docker run -name my_application_instance -p 80:80 -i -t my_application_img

现在您可以访问您的 Droplet 的 IP 地址,您的应用程序将通过 docker 容器运行。

例子:

# Usage: Visit http://[my droplet's ip]
http://95.85.10.236/

示例响应:

Hello World!

有关安装 docker(包括其他操作系统)的完整说明,请查看 docker.io 上的 docker 安装文档。

提交人: [[“%3Ca|https]] ://twitter.com/ostezer [[“%3C/a|”>操作系统]] 泰泽