Docker 解说:如何将 Python 网络应用程序容器化

<$>[警告]

状态: 已弃用

本文已弃用,不再维护。

原因

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

See Instead

<$>

简介


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

在这篇DigitalOcean文章中,我们将讨论如何将Python Web应用程序)。为了实现这一点,我们将逐步创建一个docker 容器来托管一个PythonWeb应用程序,最后使用一个Docker文件引导我们的构建过程以使其完全自动化。

词汇表


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.安装基本工具
  3. Python和基本Python工具的基本安装说明 8.应用程序部署 9.引导一切 10.最终Dockerfile 11.使用Dockerfile自动构建容器

Docker简介


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

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

注意: 要了解更多关于docker及其部件(例如docker daemon,CLI,images等),查看我们的介绍文章:** docker Explained** :Getting Started

在Ubuntu上安装Docker(最新)


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

请记住,您可以通过使用DigitalOcean基于Ubuntu 13.04构建的即用型Dock镜像快速入门。

我们将快速浏览Ubuntu(最新版)的安装过程。

Ubuntu安装说明


更新你的Drop:

1sudo aptitude update
2sudo aptitude -y upgrade

确保aufs支持可用:

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

将docker仓库密钥添加到apt-key中进行套餐验证:

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

将docker仓库添加到智能资源中:

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

用新增内容更新仓库:

1sudo aptitude update

最后,下载安装docker:

1sudo aptitude install lxc-docker

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

启用UFW转发:

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

1sudo nano /etc/default/ufw

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

替换:

1DEFAULT_FORWARD_POLICY="DROP"

与:

1DEFAULT_FORWARD_POLICY="ACCEPT"

CTRL+X 并用** Y** 进行审批即可保存并关闭。

最后,重新加载UFW:

1sudo ufw reload

Docker基本命令


在我们开始使用Docker之前,让我们快速浏览一下它的可用命令,以回顾我们的第一篇文章Geting Started ]。

运行docker守护进程和CLI使用


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

运行docker守护进程:

1sudo docker -d &

坞站命令行界面使用情况

1sudo docker [option] [command] [arguments]

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

Docker命令


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

附加


连接到正在运行的容器

搭建


从Dockerfile构建容器

提交


根据容器的更改创建新图像

cp


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

不同


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

事件


从服务器获取实时事件

导出


将容器的内容作为TAR归档进行流式传输

历史


显示图像的历史

图片


列出图像

导入


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

[]信息


显示系统范围的信息

插入


在图像中插入文件

检查


返回容器的低级信息

杀戮


杀死一个正在运行的集装箱

加载


从TAR存档加载图像

登录


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

日志


取一个集装箱的原木

端口


查找NAT转换为私有端口的面向公共的端口

ps


列出容器

pull


从docker注册服务器拉取映像或存储库

推流


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

重启


重新启动正在运行的容器

rm


移除一个或多个容器

--


删除一个或多个图像

运行


在新容器中运行命令

保存


将图像保存到TAR存档

搜索


在docker索引中搜索图像

启动


启动已停止的容器

停止


停止正在运行的集装箱

标签


将图像标记到存储库中

TOP


检查容器的运行进程

版本


显示docker版本信息

搭建Docker容器到沙盒Python WSGI应用


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

注意: 以下部分将使您拥有一个停靠(容器化)的Python WSGI Web应用程序。然而,由于它的复杂性和不切实际,它绝对不是推荐的方法。本文旨在为您提供一个学习如何使用活动容器的机会,并熟悉我们将在下一节后面定义的用于自动化该过程的命令。

开始吧!


从Ubuntu创建基础Docker容器


使用docker的run命令,我们将开始创建一个基于Ubuntu镜像的新容器。我们将使用**-t** 标志在其上附加一个终端,并将** bash** 作为运行进程。

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

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

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

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

要将您自己连接回此容器,请执行以下操作:

1.使用sudo docker ps列出所有正在运行的容器 2.查找其ID 3.使用sudo docker Attach[id]连接回其终端

重要提示: 请不要忘记,由于我们在容器中,因此以下所有命令都将在容器中执行,而不会影响其所在的主机。

准备安装基容器


为了在容器中部署PythonWSGI Web应用程序--以及我们在该过程中所需的工具--相关的应用程序存储库必须可供下载。不幸的是(为了简单起见)这与docker附带的默认Ubuntu镜像**不同。

让我们将Ubuntu的语义库附加到基本映像的默认应用程序源列表中。

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

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

1apt-get update

在我们继续设置PythonWSGI应用程序之前,我们应该准备一些工具,如Nano、tar、curl等--只是为了以防万一。

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

1apt-get install -y tar \
2                   git \
3                   curl \
4                   nano \
5                   wget \
6                   dialog \
7                   net-tools
8                   build-essential

安装部署常用的Python工具


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

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

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

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

安装Web应用及其依赖关系


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

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

1# Download and install Flask framework:
2pip install flask

安装pip后,让我们在包含所有内容的my_app文件夹中创建一个基本的样例FlaskTM应用程序。

1# Make a my_application folder
2mkdir my_application
3
4# Enter the folder
5cd my_application

注意: 如果您想部署您的应用程序,而不是这个简单的示例,请参阅下面的** 快速提示** 部分。

让我们创建一个单独的、一页的瓶子Hello World!使用纳米技术的应用。

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

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

1from flask import Flask
2app = Flask(__name__)
3
4@app.route("/")
5def hello():
6    return "Hello World!"
7
8if __name__ == "__main__":
9    app.run()

按CTRL+X并按Y进行审批,保存并关闭。

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

要使用Nano文本编辑器创建Requirements s.txt,请执行以下操作:

1nano requirements.txt

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

1flask
2cherrypy

按CTRL+X和批准与Y保存和关闭。

注意: 您可以使用** pip** 创建您的实际应用程序依赖列表。要了解如何使用,请查看我们的教程常见的PythonTool:使用Virtualenv、使用pip安装和管理Packages.

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

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

注意: 请参考下面关于server.py的部分-** 配置您的Python WSGI应用程序** 。

请记住 :此应用程序文件夹将在容器内创建。当您自动构建镜像时(请参阅下面关于Dockerfile的一节),您将需要确保在主机上与Dockerfile一起具有此结构。

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

如何将您的应用仓库及其需求放入容器中


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

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

以下是其中两个问题的解释:

 1# Example [1]
 2# Download the application using git:
 3# Usage: git clone [application repository URL]
 4# Example:
 5git clone https://github.com/mitsuhiko/flask/tree/master/examples/flaskr
 6
 7# Example [2]
 8# Download the application tarball:
 9# Usage: wget [application repository tarball URL]
10# Example: (make sure to use an actual, working URL)
11wget http://www.github.com/example_usr/application/tarball/v.v.x
12
13# Expand the tarball and extract its contents:
14# Usage: tar vxzf [tarball filename .tar (.gz)]
15# Example: (make sure to use an actual, working URL)
16tar vxzf application.tar.gz
17
18# Download and install your application dependencies with pip.
19# Download the requirements.txt (pip freeze output) and use pip to install them all:
20# Usage: curl [URL for requirements.txt] | pip install -r -
21# Example: (make sure to use an actual, working URL)
22curl 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:

1pip install cherrypy

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

1nano server.py

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

 1# Import your application as:
 2# from app import application
 3# Example:
 4
 5from app import app
 6
 7# Import CherryPy
 8import cherrypy
 9
10if __name__ == '__main__':
11
12    # Mount the application
13    cherrypy.tree.graft(app, "/")
14
15    # Unsubscribe the default server
16    cherrypy.server.unsubscribe()
17
18    # Instantiate a new server object
19    server = cherrypy._cpserver.Server()
20
21    # Configure the server object
22    server.socket_host = "0.0.0.0"
23    server.socket_port = 80
24    server.thread_pool = 30
25
26    # For SSL Support
27    # server.ssl_module            = 'pyopenssl'
28    # server.ssl_certificate       = 'ssl/certificate.crt'
29    # server.ssl_private_key       = 'ssl/private.key'
30    # server.ssl_certificate_chain = 'ssl/bundle.crt'
31
32    # Subscribe this server
33    server.subscribe()
34
35    # Start the server engine (Option 1 *and* 2)
36
37    cherrypy.engine.start()
38    cherrypy.engine.block()

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

1python server.py

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

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

1python server.py &

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

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

要测试一切是否运行顺利,考虑到所有端口分配都已得到处理,您可以使用浏览器访问http://[your Droplet的IP] ,以查看** Hello World!** 消息。

创建Dockerfile自动构建镜像


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

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

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

Dockerfile基础知识


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

这些文件始终以使用FROM命令定义基本映像开始。从那时起,_Build_Process_开始,随后采取的每一项操作都形成将在主机上提交的最终映像。

用途:

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

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

Dockerfile命令概述


添加


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

CMD


设置要执行的默认命令或将其传递给入口点

切入点


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

ENV


设置环境变量(如)

博览会


将端口暴露在外

来自


设置要使用的基本图像

维护者


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

运行


运行命令并提交结束结果(容器)映像

用户


将用户设置为从映像运行容器


将目录从主机挂载到容器

工作目录


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

创建Dockerfile


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

1sudo nano Dockerfile

注: 将以下各行逐行追加,即构成Dockerfile。

定义基础知识


让我们从定义基础(基础)开始我们的Dockerfile,比如From映像(即Ubuntu)和维护者。

添加以下内容:

 1############################################################
 2# Dockerfile to build Python WSGI Application Containers
 3# Based on Ubuntu
 4############################################################
 5
 6# Set the base image to Ubuntu
 7FROM ubuntu
 8
 9# File Author / Maintainer
10MAINTAINER Maintaner Name

更新安装默认应用仓库


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

添加以下内容:

1# Add the application resources URL
2RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list
3
4# Update the sources list
5RUN apt-get update

安装基础工具


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

添加以下内容:

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

注意: 虽然您不太可能需要上面的一些工具,但我们仍然会提供它们--只是以防万一。

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


要部署PythonWSGI应用程序,您极有可能需要一些我们以前使用过的工具(例如_pip_)。现在让我们先安装它们,然后再继续设置框架(即您的WAF)和您选择的Web应用程序服务器(Was)。

添加以下内容:

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

应用部署


考虑到我们正在构建docker映像来部署PythonWeb应用程序,我们都可以利用docker的添加命令来复制应用程序存储库,最好是使用一个需求文件,以便在单个步骤中快速运行。

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

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

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

注意: 如需了解如何创建此结构,请回滚并参考** 安装Web应用程序及其附件 ** 一节。

添加以下内容:

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

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

1RUN git clone [application repository URL]

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

一切自举


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

 1# Get pip to download and install requirements:
 2RUN pip install -r /my_application/requirements.txt
 3
 4# Expose ports
 5EXPOSE 80
 6
 7# Set the default directory where CMD will execute
 8WORKDIR /my_application
 9
10# Set the default command to execute
11# when creating a new container
12# i.e. using CherryPy to serve the application
13CMD python server.py

♪最终文档文件


最后,Dockerfile应该是这样的:

 1############################################################
 2# Dockerfile to build Python WSGI Application Containers
 3# Based on Ubuntu
 4############################################################
 5
 6# Set the base image to Ubuntu
 7FROM ubuntu
 8
 9# File Author / Maintainer
10MAINTAINER Maintaner Name
11
12# Add the application resources URL
13RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list
14
15# Update the sources list
16RUN apt-get update
17
18# Install basic applications
19RUN apt-get install -y tar git curl nano wget dialog net-tools build-essential
20
21# Install Python and Basic Python Tools
22RUN apt-get install -y python python-dev python-distribute python-pip
23
24# Copy the application folder inside the container
25ADD /my_application /my_application
26
27# Get pip to download and install requirements:
28RUN pip install -r /my_application/requirements.txt
29
30# Expose ports
31EXPOSE 80
32
33# Set the default directory where CMD will execute
34WORKDIR /my_application
35
36# Set the default command to execute    
37# when creating a new container
38# i.e. using CherryPy to serve the application
39CMD python server.py

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

使用Dockerfile自动构建容器


正如我们在基础部分首先介绍的那样,Dockerfile的使用包括使用docker Build 命令调用它们。

由于我们指示docker从当前目录复制一个应用程序文件夹(即/my_app),因此在开始构建过程之前,我们需要确保将其与该Dockerfile放在一起。

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

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

1sudo docker build -t my_application_img .

使用该映像--我们将其标记为my_app_img--我们可以运行一个新的容器来运行该应用程序:

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

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

示例:

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

回复示例:

1Hello World!

有关安装Docker(包括其他操作系统)的全套说明,请查看Docker安装文档,网址:docker.io .

Submitted by: O.S. Tezer
Published At
Categories with 技术
comments powered by Disqus