Part 2: Containers

要求

  • 安装了1.13或者更高版本的Docker

  • 阅读了Part1中的定位(我没写)

介绍

是时候用Docker构建一个app了。我们会从构建这样一个app的最底层开始,容器——我们这节所介绍的内容。在这层之上是服务,服务定义了容器们的在生产中的行为,在第3章介绍。最上层的是堆,定义了服务的交互行为,在第5章介绍。

  • 堆(Stack)

  • 服务(Services)

  • 容器(container)

新开发环境

使用docker,您可以直接获取一个可移植的Python运行时作为映像。然后,您的构建可以在应用程序代码旁边包含基本的Python映像,确保应用程序、它的依赖项和运行时环境一起运行。

Dockerfile定义一个容器

Dockerfile将定义容器内环境的内容。访问像网络接口和磁盘驱动器之类的资源在这个环境中是虚拟化的,这与系统的其他部分是隔离的,因此您必须将端口映射到外部世界,并具体地说明您想要“复制”到该环境中的文件。然而,在做了这些之后,您可以期望在这个Dockerfile中定义的应用程序的构建在运行的任何地方都是完全相同的。

Dockerfile

创建一个空目录。将目录(cd)更改为新目录,创建一个名为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 --trusted-host pypi.python.org -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"]

您是否使用了代理服务器?

代理服务器一旦启动并运行,就可以阻塞连接到您的web应用程序。如果您在代理服务器后面,请在Dockerfile中添加以下几行,使用ENV命令为您的代理服务器指定主机和端口:

# Set proxy server, replace host:port with values for your servers
ENV http_proxy host:port
ENV https_proxy host:port

这个Dockerfile和我们还没有创建的两个文件有联系,即app.py和requirements.txt。接下来让我们创建这些。

应用程序本身

创建两个更多的文件,requirements.txt和app.py,并将它们放在与Dockerfile相同的文件夹中。这就完成了我们的应用程序,正如您所看到的非常简单。当上述Dockerfile被构建成一个Image,由于Dockerfile的ADD命令会添加requirements.txt和app.py,感谢EXPOSE使app.py的输出可以通过HTTP访问。

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 .

你的构建的Image在哪里?就在你的机器的本地Docker图像注册表中:

$ docker imagesREPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

提示:您可以使用命令docker images或较新的docker image ls查看所有的镜像。它们给出相同的输出。

运行应用

运行应用程序,使用-p,将您的机器的端口4000映射到容器已经发布的端口80:

docker run -p 4000:80 friendlyhello

您应该看到一条消息,Python正在以http://0.0.0.0:80为您的应用服务。但是这个消息来自容器内部,它不知道您将该容器的80端口映射到4000,从而使正确的URL http://localhost:4000。
在web浏览器中访问该URL,可以看到web页面上显示的显示内容,包括“Hello World”文本、容器ID和Redis错误消息。

clipboard.png

注意:如果您在Windows 7上使用Docker工具,使用Docker机器IP而不是localhost。例如,http://192.168.99.100:4000。要查看IP地址,请使用命令docker -machine IP。

您还可以在shell中使用curl命令来查看相同的内容。

$ curl http://localhost:4000<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

这个端口映射4000:80是为了演示在Dockerfile中公开的内容和使用docker run - p发布的内容之间的区别。在后面的步骤中,我们将把端口80映射到容器中的80端口,并使用http://localhost。
在你的终端按CTRL + C退出。

现在让我们在后台运行应用程序,在分离的模式下:

docker run -d -p 4000:80 friendlyhello

你得到了你的应用程序的容器长ID,然后被离开你的终端。您的容器将在后台运行。您还可以看到缩写容器ID通过docker container ls(在运行命令时,这两个工作都可以互换):

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

您将看到匹配http://localhost:4000上的CONTAINER ID

现在使用docker容器停止进程,使用容器ID,例如:

docker container stop 1fa4ab2cf395

分享你的镜像

为了演示我们刚刚创建的可移植性,让我们上传我们构建的映像并在其他地方运行它。毕竟,当您想要将容器部署到生产时,您需要学习如何推动注册。

注册表是存储库的集合,而存储库是镜像的集合——有点像GitHub库,只是代码已经构建好了。注册表上的帐户可以创建许多存储库。docker CLI在默认情况下使用docker的公共注册表。

注意:我们将在这里使用Docker的公共注册表,因为它是免费和预配置的,但是有许多公共注册中心可供选择,而且您甚至可以使用Docker可信注册表建立您自己的私有注册表。

使用您的Docker ID登录

如果你没有Docker帐户,在cloud.docker.com注册一个。记下你的用户名。

登录到本地机器上的Docker公共注册表。

$ docker login

标记镜像

将本地映像与注册表中的存储库关联的符号是username/repository:tag。标签是可选的,但推荐,因为它是注册中心用来给Docker映像提供一个版本的机制。提供存储库并为上下文标记有意义的名称,例如get - started:part2。这将把镜像放到get-started存储库中,并将其标记为part2。

docker tag image username/repository:tag

例如:

docker tag image username/repository:tag

运行docker image以查看新标记的图像。(您也可以使用docker image ls)

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
john/get-started         part2               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB
...

发布镜像

将您的标记镜像上载到存储库

docker push username/repository:tag

一旦完成,这个上传的结果是公开的。如果您登录到Docker Hub,您将在那里看到新的图像,使用它的pull命令。

从远程存储库中提取和运行映像

从现在开始,你可以使用docker run在任何机器上运行你的应用程序:

docker run -p 4000:80 username/repository:tag

如果映像在机器上没有本地可用,Docker将从存储库中提取该映像。

$ docker run -p 4000:80 john/get-started:part2
Unable to find image 'john/get-started:part2' locally
part2: Pulling from john/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for john/get-started:part2* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

注意:如果您没有指定这些命令的标记部分:tag,那么将会假定您在构建和运行映像时都将使用最新的标记:latest。Docker将使用没有指定标记的图像的最后一个版本(不一定是最近的图像)。

无论docker运行在哪里,它都会拉出您的映像,以及Python以及来自需求的所有依赖项requirements.txt,并运行您的代码。它在一个整洁的小程序包中一起运行,而主机不需要安装任何东西,而是安装Docker来运行它。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540105.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(论文)WS-DAN (弱监督数据增强)

背景 近期在做外卖分类的项目&#xff0c;外卖分类属于细粒度图像分类&#xff0c;在分类的过程中要从图片的行人中和非机动车中区分出各类外卖&#xff08;主要是美团、饿了吗&#xff09;。刚好近期发现了一片关于细粒度图像分类较新的论文&#xff08;See Better Before Lo…

罗马音平假名片假名转换器_关于五十音你所要知道的一切!文末附日网高清字帖...

今天开始&#xff0c;木子小花日本语教室将开始同时更新日语文法系列文章 和 日语真题详解系列文章&#xff0c;从五十音图的记忆方法到日语助词的用法整理&#xff0c;从N5的简单句子构成到N1复杂文法的接续记忆方法&#xff0c;力求做出全知乎&#xff08;小声&#xff1a;全…

django的web开发笔记1(智能诊断系统数据概览记录)

接于上一篇&#xff0c;这一篇主要记录如何链接mysql数据库以及从数据库中调用数据信息到页面&#xff0c;同时包含百度地图api的一些使用。 其中包括模块&#xff0c;echert图表绘制数据调用&#xff0c;百度地图数据信息调用以及一些单机效果&#xff0c;页面数据调用等。 1…

左右xcode的重构选项的一些理解

Rename(重命名):对标示符进行重命名,以获得更好的代码可读性,这些标示符包含类,方法或者函数的名称. Extract(抽取):将你在XCode种选择的代码抽取到一个新的方法或函数中. Create SuperClass(创建父类):为Xcode中当前所选的类定义父类 Move Up(上移):将所选择的方法,属性,或实例…

window 如何查看tomcat 实时日志_如何处理生产环境Tomcat的catalina.out日志?

前语&#xff1a;不要为了读文章而读文章&#xff0c;一定要带着问题来读文章&#xff0c;勤思考。作者&#xff1a;jmcui 来源&#xff1a;http://1t.click/x4q# 前言随着每天业务的增长&#xff0c;Tomcat 的catalina.out日志 变得越来越大&#xff0c;占用磁盘空间不说。要…

paddlepaddle测试安装_百度paddlepaddle深度学习7日入门-CV疫情特辑心得

正值疫情严重之日&#xff0c;作为一名研究生被迫待在家里学习&#xff0c;手头的科研项目也严重受挫。。。偶然间&#xff0c;看到微信公众号发布这门课&#xff0c;马上报名&#xff0c;入坑&#xff01;&#xff01;&#xff01;瞬间疫情其间有学习的目标了。。该课程学习依…

apache目录 vscode_VsCode搭建Java开发环境(Spring Boot项目创建、运行、调试)

VsCode搭建Java开发环境(Spring Boot项目创建、运行、调试)安装如下两个主要扩展即可&#xff0c;这两个扩展已关联java项目开发主要使用的maven、springboot等所需要的扩展。开始步骤&#xff1a;在 Visual Studio Code 中打开扩展视图(CtrlShiftX)。输入“java”搜索商店扩展…

android dp转px的公式_Android特效专辑——自定义不一样的Toast

大家都知道&#xff0c;Android的控件有时候很难满足我们的需求&#xff0c;所以我们需要自定义View。自定义的方式很多&#xff0c;有继承原生控件也有直接自定义View的&#xff0c;今天写的是自定义的Toast&#xff0c;当然&#xff0c;这个不是复写Toast,是换一种表达形式&a…

code iban 是有什么组成_深入浅出Zookeeper(四):客户端的请求在服务器中经历了什么...

作者 泊浮目 沃趣科技高级研发工程师出品 沃趣科技1. 前言当我们向zk发出一个数据更新请求时&#xff0c;这个请求的处理流程是什么样的&#xff1f;zk又是使用了什么共识算法来保证一致性呢&#xff1f;带着这些问题&#xff0c;我们进入今天的正文。2. 设计模式&#xff1…

启动activemq_「Java」 - SpringBoot amp; ActiveMQ

一、消息队列消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合、异步消息、流量削锋等问题&#xff0c;实现高性能、高可用、可伸缩和最终一致性架构&#xff0c;是大型分布式系统不可缺少的中间件。目前在生产环境中使用较多的消息队列有ActiveMQ、Rabbit…

永不休眠怎么设置_电脑休眠后应该怎样唤醒?

可能有朋友会碰到这种情况&#xff0c;电脑屏幕显示正在休眠&#xff0c;而且不停的转圈&#xff0c;这是怎么回事&#xff0c;如何唤醒?下面让坚哥为大家分析一下吧。电脑开机显示休眠一般根据以下几种情况进行处理&#xff1a;1、正常电脑休眠&#xff1a;一般的是按一下电源…

配置ssl证书_Mysql配置ssl证书

本环境基于mysql5.6配置&#xff0c;通过openssl生成证书进行配置一、确认环境信息1、查看数据库版本mysql> select version();-----------| version() |-----------| 5.6.36 |-----------2、查看数据库是否支持ssl配置mysql> show variables like have%ssl%;-----------…

如何让图片充满excel单元格_如何在Excel单元格建立下拉菜单

对于一些常用的数据我们往往会希望能够尽量快速的输入&#xff0c;下拉菜单就是一个最简单的解决办法。那么如何实现下拉菜单呢&#xff1f;跟随以下步骤&#xff0c;建立属于自己的下拉菜单吧&#xff01;如何建立下拉菜单&#xff1f;一、确定内容&#xff1a;在单元格中&…

pgsql中float4导致java程序精度丢失_Java基础系列02

注释Java中支持三种注释&#xff1a;1.单行注释以//开始换行结束。2.多行注释以/*开始&#xff0c;以*/结束。3.说明注释以/**开始&#xff0c;以*/结束。关键字关键字&#xff1a;是指在程序中&#xff0c;Java已经定义好的单词&#xff0c;具有特殊含义。例如上篇文章中Hello…

用idea建立jsp项目_用idea创建maven项目,配置tomcat详解

用idea创建maven项目&#xff0c;配置tomcat详解&#xff0c;电脑上得有jdk1.7&#xff0c;或者1.8&#xff0c;然后就是maven3.x吧&#xff0c;再有就是tomcat7以上下面就直接开始看图啦&#xff1a;这个我刚刚开始没注意细看&#xff0c;原来web app 的骨架有2个呢&#xff0…

求立方根_初一数学立方根考点详解,立足基础,把握题型,学会方法

初一数学实数部分&#xff0c;平方根和立方根这两部分的知识点比较的基础&#xff0c;但是考试中却是经常会考&#xff0c;并且有很多的“陷阱”&#xff0c;也是让学生猝不及防&#xff0c;今天我和同学们继续学习交流立方根的知识点&#xff0c;通过详解考点&#xff0c;帮助…

mysql双主数据一致性_MySQL双主一致性架构优化 | 架构师之路-阿里云开发者社区...

一、双主保证高可用MySQL数据库集群常使用一主多从&#xff0c;主从同步&#xff0c;读写分离的方式来扩充数据库的读性能&#xff0c;保证读库的高可用&#xff0c;但此时写库仍然是单点。在一个MySQL数据库集群中可以设置两个主库&#xff0c;并设置双向同步&#xff0c;以冗…

spool导出姓名中文乱码_MySQL不同字符集转化标准—7步实现,杜绝乱码!

引言作为资深的DBA程序员&#xff0c;在工作中是否会遇到更这样的情况呢&#xff1f;原有数据库的字符集由于前期规划不足&#xff0c;随着业务的发展不能满足业务的需求。如原来业务系统用的是utf8字符集&#xff0c;后期有存储表情符号的需求&#xff0c;uft8字符集就不能满足…

easyexcel 设置标题_使用easyexcel完成复杂表头及标题的导出功能(自定义样式)

如需客户端指定excel版本,只需要判断后缀名然后在controller中的.excelType(ExcelTypeEnum.XLS)做指定输出内容格式即可***(注意表格行高列宽统一设置是在实体类的类名注解上,如果需要对表格进行精细的宽高设置需要删除掉这两个注解,可以在拦截器使用row的方法进行设置)1. ## 引…

nmon安装为什么重启mysql_Nmon的安装及使用

一、下载Nmon根据CPU的类型选择下载相应的版本&#xff1a;二、初始化工具[rootmululu ~]# cd /opt[rootmululu opt]# mkdir nmon[rootmululu opt]# cd nmon[rootmululu nmon]#wget http://sourceforge.net/projects/nmon/files/download/nmon_x86_12a.zip[rootmululu nmon]# u…