介绍
将Web应用程序劫持并用于接管整个主机的威胁是一个巨大而可怕的威胁。 长期以来,为了增强安全性而将事物彼此隔离是一个挑战,特别是如果应用程序属于不同的客户端。 可以采取许多措施来防止这种不幸的情况,然而,它们通常太昂贵(对于时间和资源)或对于大多数开发人员或管理员的使用情况来说太复杂。
在这篇DigitalOcean文章中,我们将讨论“容器化”Python Web应用程序,以便将它们放在非常安全的沙盒中,绝对保存在自己的环境中(除非你明确地将它们链接到另一个)。 为了实现这一目标,我们将看到有关创建Docker容器举办一个Python的Web应用程序一步一步,终于自引导我们用Dockerfile的构建过程完全自动化。
词汇表
Docker简介
2.在Ubuntu上安装Docker
3.基本Docker命令
- 运行docker守护程序和CLI用法
- docker命令
4.构建Docker容器到Sandbox Python WSGI应用程序
- 从Ubuntu创建基本Docker容器
- 准备安装的基本容器
- 安装常见的Python工具进行部署
- 安装Web应用程序及其依赖关系
- 配置Python WSGI应用程序
5.创建Dockerfile以自动构建映像
- Dockerfile基础
- Dockerfile命令概述
- 创建Dockerfile
- 定义基础
- 更新安装的默认应用程序存储库
- 安装基本工具
- Python和基本Python工具的基本安装说明
- 应用程序部署
- 引导一切
- 最终Dockerfile
- 使用Dockerfile自动构建容器
Docker简介
该项目Docker提供了更高级别的工具,一起工作,这是建立在某些Linux内核特性之上。 我们的目标是帮助开发人员和系统管理员移植应用-与它们的依赖关系的共同地-并让他们在系统和机器上运行- 免费头疼 。
Docker通过创建安全实现这一目标,LXC(即Linux的容器)为基础的所谓Docker容器的应用环境。 这些容器在使用搬运工图像,这可以通过Dockerfiles手动或自动执行命令建立创建。
注意:要了解更多关于Docker及零部件(如Docker守护进程,CLI,图像等),看看我们的介绍性文章,以项目: Docker解释 :入门 。
在Ubuntu上安装Docker(最新)
凭借其最新的版本(0.7.1。约会12月5日),Docker可以部署在各种Linux操作系统,包括Ubuntu / Debian的和CentOS / RHEL。
记住,你可以快速开始使用DigitalOcean的即用型Docker镜像建立在Ubuntu 13.04上。
我们将快速完成Ubuntu的安装过程(最新)。
Ubuntu的安装说明
更新您的Droplet:
sudo aptitude update
sudo aptitude -y upgrade
确保aufs支持可用:
sudo aptitude install linux-image-extra-`uname -r`
将docker repository key添加到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:单纯性防火墙)默认情况下,它是由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的工作之前,让我们赶紧去了其可用的命令,从我们第一次刷新我们的记忆入门文章。
运行docker守护程序和CLI用法
安装后,docker守护程序应该在后台运行,准备接受docker CLI发送的命令。 对于可能需要手动运行docker的某些情况,请使用以下命令。
运行docker守护进程:
sudo docker -d &
docker CLI用法:
sudo docker [option] [command] [arguments]
注:Docker需要为了工作sudo的特权。
Docker命令
下面是目前可用的(0.7.1版本)Docker命令的摘要:
连接
附加到正在运行的容器
建立
从Dockerfile构建容器
承诺
从容器的更改创建新图像
cp
将文件/文件夹从容器文件系统复制到主机路径
差异
检查容器文件系统上的更改
事件
从服务器获取实时事件
出口
将容器的内容作为tar存档进行流式传输
历史
显示图像的历史记录
图片
列出图像
进口
从tarball的内容创建新的文件系统映像
信息
显示系统范围的信息
插
在图像中插入文件
检查
返回容器上的低级信息
杀
杀死一个正在运行的容器
加载
从tar存档加载映像
登录
注册或登录到docker注册表服务器
日志
获取容器的日志
港口
查找NAT-ed到PRIVATE_PORT的面向公众的端口
ps
列出容器
拉
从docker注册表服务器中拉取图像或存储库
推
将图像或存储库推送到docker注册表服务器
重新开始
重新启动正在运行的容器
rm
删除一个或多个容器
rmi
删除一个或多个图像
跑
在新容器中运行命令
保存
将图像保存到tar存档
搜索
在docker索引中搜索图像
开始
启动已停止的容器
停止
停止正在运行的容器
标签
将图像标记到存储库中
最佳
查找容器的运行进程
版
显示docker版本信息
构建Docker容器到Sandbox 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可能需要为您创造一个新的容器之前拉 Ubuntu的形象。
记住:你将被连接到您所创建的容器。 为了分离自己并返回到您的主终端接入点,运行转义序列:CTRL + P后跟CTRL + Q。 附加到docker容器就像连接到另一个内部的一个新的Droplet。
要将自己重新添加到此容器中:
使用“sudo docker ps”列出所有正在运行的容器
查找其ID
使用“sudo docker attach [id]”附加到它的终端
重要提示:请不要忘记,因为我们是在一个容器,下面所有的命令将被那里执行,而不会影响它所在的主机。
准备安装的基本容器
为了在容器中部署Python WSGI Web应用程序 - 以及进程所需的工具,相关的应用程序库必须可用于下载。 不幸的是(和故意让事情变得简单),这是不附带DockerUbuntu默认的图像的情况。
让我们将Ubuntu的Universe存储库附加到基本映像的应用程序源列表的默认列表。
echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sources.list
使用新添加的源更新列表。
apt-get update
之前,我们与设立的Python WSGI应用程序进行,有一些手段,我们应该有如纳米,tar,卷曲等- 以防万一 。
让我们下载我们的容器内一些有用的工具。
apt-get install -y tar \
git \
curl \
nano \
wget \
dialog \
net-tools
build-essential
安装常见的Python工具进行部署
对于我们的教程(作为一个例子),我们将创建一个非常基本的应用瓶 。 在阅读本文后,您可以使用和部署您最喜欢的框架,就像在虚拟服务器上部署它一样。
记住:所有的命令和指示之下仍然需要一个容器,它的作用几乎一样,如果这是它自己的一个全新的Droplet内部发生。
让我们开始我们的部署进程,安装Python和PIP的Python包管理器:
# Install pip's dependency: setuptools:
apt-get install -y python python-dev python-distribute python-pip
安装Web应用程序及其依赖关系
在我们开始创建示例应用程序之前,我们最好确保一切 - 即所有依赖关系 - 都在那里。 首先,你可能有你的Web应用程序框架(WAF)作为你的应用程序的依赖(即Flask)。
因为我们已经安装了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
注意:如果你有兴趣在部署应用程序,而不是这个简单的样品的例子,请参阅“ 快速提示 ”的中间部分。
让我们创建一个单一的一页Flask“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应用 。
记住 :这个应用程序文件夹将容器内创建。 当你自动构建图像(参见下面关于Dockerfiles的部分)时,你需要确保主机上有这个结构,以及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后面)按照我们的教程。
下载并安装CherryPy与pip:
pip install cherrypy
从“app.py”创建一个“server.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的部署,看看我们的教程: 如何部署的Python WSGI应用使用的CherryPy的Web服务器
为了测试一切顺利运行,这是他们应该给所有的端口分配已经照顾,你可以访问http:// [您Droplet的IP]与你的浏览器中看到这个“Hello World!” 信息。
创建Dockerfile以自动构建映像
正如我们在上一步中所提到的,肯定不是以这种方式为可扩展生产部署创建容器的建议方法。 正确的做法可以被认为是使用Dockerfiles以一种结构化的方式自动化构建过程。
在经过用于在容器中下载和安装的必要命令之后,我们可以使用相同的知识来构建Docker可以用来构建图像的Dockerfile,然后可以轻松地运行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 .
注意:要了解更多有关Dockerfiles,看看我们的文章: Docker解释:使用Dockerfiles到自动图像大厦 。
Dockerfile命令概述
加
将文件从主机复制到容器中
CMD
设置要执行的默认命令,或传递到ENTRYPOINT
入口点
在容器中设置默认的入口点应用程序
ENV
设置环境变量(例如“key = value”)
暴露
将端口暴露给外部
从
设置要使用的基本映像
MAINTAINER
设置Dockerfile的作者/所有者数据
跑
运行命令并提交结果结果(容器)图像
用户
设置用户从映像运行容器
卷
将目录从主机挂载到容器
WORKDIR
设置目录要执行CMD的指示
创建Dockerfile
要使用nano文本编辑器在当前位置创建Dockerfile,请执行以下命令:
sudo nano Dockerfile
注意:追加所有下列行一前一后,形成Dockerfile。
定义基础
让我们通过定义基础(基础)开始我们的Dockerfile,如FROM映像(即Ubuntu)和MAINTAINER。
附加以下内容:
############################################################
# 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应用程序,你极有可能需要一些我们合作过的工具(如PIP)。 让我们现在安装它们,然后继续设置框架(即您的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]
请不要忘记将网址占位符替换为您的实际网址。
引导一切
添加复制应用程序的指令后,让我们完成最后的配置,如从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“使用由带有Dockerbuild命令调用它们。
因为我们指示Docker从当前目录复制一个应用程序文件夹(即/ my_application),所以我们需要确保在开始构建过程之前将它放在这个Dockerfile旁边。
这个docker镜像将允许我们使用单个命令快速创建运行Python WSGI应用程序的容器。
要开始使用它,请使用以下内容构建新的容器图像:
sudo docker build -t my_application_img .
并使用图像-这是我们的标签我的应用程序 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.ioDocker安装文档 。