先决条件
- 安装Docker 1.13或更高版本。
- 阅读第1部分
- 为您的环境快速测试运行,以确保您全部设置:
docker run hello-world
介绍
现在是开始构建Docker应用程序的时候了。我们将从这样一个应用程序的层次结构的底部开始,这是一个容器,我们在这个页面上介绍。在这个层次之上是一个服务,它定义了容器在生产中的行为方式,这在第3部分中有所描述。最后,在顶层是堆栈,定义所有服务的交互, 第5部分将介绍。
- 堆
- 服务
- 集装箱(你在这里)
您的新开发环境
过去,如果要开始编写一个Python应用程序,您的第一个业务是将Python运行时安装到您的机器上。但是,这会造成您的机器上的环境必须如此,以便您的应用程序按预期运行的情况; 同时运行您的应用程序的服务器。
使用Docker,您只需抓取可移植的Python运行时即可,无需安装。然后,您的构建可以将应用程序代码旁边的基本Python图像包含在内,确保您的应用程序,其依赖关系和运行时都一起运行。
这些便携式图像由所谓的a定义Dockerfile。
用a定义一个容器 Dockerfile
Dockerfile将会定义容器内部的环境。访问资源(如网络接口和磁盘驱动器)在此环境中进行虚拟化,这与您系统的其他部分是隔离的,因此您必须将端口映射到外部世界,并具体说明要将哪些文件“复制”到那个环境。但是,在这样做之后,您可以期望在其中定义的应用程序的构建 Dockerfile将在运行的任何地方运行。
Dockerfile
创建一个空目录,并将该文件放在其中,名称Dockerfile。注意解释每个陈述的意见。
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
这Dockerfile是指我们还没有创建的几件事情,即 app.py和requirements.txt。让我们来接下来的那些。
应用本身
抓住这两个文件,并将它们放在同一个文件夹中Dockerfile。这完成了我们的应用程序,你可以看到它是非常简单的。当上述 Dockerfile被内置到的图像,app.py并且requirements.txt将存在因为这样Dockerfile的ADD命令,并从输出 app.py将超过HTTP得益于访问EXPOSE命令。
requirements.txt
Flask
Redis
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
现在我们看到,pip install -r requirements.txt为Python安装Flask和Redis库,应用程序会打印环境变量NAME以及调用的输出socket.gethostname()。最后,因为Redis没有运行(因为我们只安装了Python库,而不是Redis本身),我们应该期望在这里使用它的尝试将失败并产生错误消息。
注意:在容器内部访问主机的名称将检索容器ID,这与运行的可执行文件的进程ID类似。
构建应用程序
而已!您不需要Python或requirements.txt系统中的任何内容,也不构建或运行此映像将其安装在系统上。你似乎并没有真正使用Python和Flask来设置一个环境,但是你已经有了。
这是ls应该显示的:
$ ls
Dockerfile app.py requirements.txt
现在运行build命令。这将创建一个Docker图像,我们将使用-t它来标记,因此它具有友好的名称。
docker build -t friendlyhello .
你的图像在哪里?它在您机器的本地Docker映像注册表中:
$ docker images
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
运行应用程序
运行应用程序,将机器的端口4000映射到容器的EXPOSEd端口80,方法-p如下:
docker run -p 4000:80 friendlyhello
您应该会看到一个通知,指出Python正在为您的应用程序提供服务http://0.0.0.0:80。但是该消息来自容器内部,不知道您将该容器的端口80映射到4000,从而形成正确的URL http://localhost:4000。
在Web浏览器中转到该URL,以查看网页上提供的显示内容,包括“Hello World”文本,容器ID和Redis错误消息。