首页 > 其他分享 >Get started with Docker 中文文档(2)——Part 2: Containers

Get started with Docker 中文文档(2)——Part 2: Containers

时间:2023-06-06 20:04:45浏览次数:39  
标签:容器 80 Get started app 应用程序 Part docker Docker


先决条件

  • 安装Docker 1.13或更高版本。
  • 阅读第1部分的方向。
  • 让您的环境快速测试,以确保您全部设置:docker run hello-world

介绍

现在是开始构建Docker应用程序的时候了。 我们将从这样一个应用程序的层次结构的底部开始,这是一个容器,我们在这个页面上介绍。 在这个层次之上是一个服务,它定义了容器在生产中的行为方式,涵盖在第3部分中。最后,顶层是堆栈,定义了所有服务的交互,第5部分所述。

  • Stack
  • Services
  • Container (you are here)

您的新开发环境

过去,如果您要开始编写Python应用程序,则您的第一个业务是将Python运行时安装到您的计算机上。 但是,这会造成您的机器上的环境必须如此,以便您的应用程序按预期运行的情况; 同时运行您的应用程序的服务器。

使用Docker,您可以将便携式Python运行时作为图像,无需安装。 然后,您的构建可以将应用程序代码旁边的基本Python图像包含在内,确保您的应用程序,其依赖关系和运行时都一起运行。

这些便携式图像由称为Dockerfile的东西定义。

定义具有Dockerfile文件的container

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

Docker文件
创建一个空目录,并将该文件放在其中,名称为Dockerfile。 注意说明每个陈述的意见。

# 使用官方Python运行时作为基础映像
FROM python:2.7-slim

# 将工作目录设置为/ app
WORKDIR /app

# 将当前目录内容复制到/ app中的容器中
ADD . /app

# 安装require.txt中指定的所需软件包
RUN pip install -r requirements.txt

# 使端口80可用于此容器外的世界
EXPOSE 80

# 定义环境变量
ENV NAME World

# 在容器启动时运行app.py
CMD ["python", "app.py"]

这个Docker文件是指我们还没有创建的几件事,即app.pyrequirements.txt。 让我们来接下来的那些。

应用程序本身

抓住这两个文件,并将它们放在与Dockerfile相同的文件夹中。 这完成了我们的应用程序,你可以看到它是非常简单的。 当上述Dockerfile内置到一个图像中时,由于该DockerfileADD命令,app.pyrequirements.txt将会出现,而通过EXPOSE命令可以通过HTTP访问来自app.py的输出。

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)

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安装require.txt安装了Python的Flask和Redis库,应用程序会打印出环境变量NAME以及对socket.gethostname()的调用输出。 最后,因为Redis没有运行(因为我们只安装了Python库,而不是Redis本身),我们应该期望在这里使用它的尝试将失败并产生错误消息。

注意:在容器内部访问主机的名称将检索容器ID,这与运行的可执行文件的进程ID类似。

构建应用程序

您的系统上的require.txt不需要Python或任何内容,也不构建或运行此映像将其安装在系统上。 你似乎并没有真正使用Python和Flask来设置一个环境,但是你已经有了。

这里是 ls 应该显示:

$ ls
Dockerfile      app.py          requirements.txt

现在运行build命令。 这将创建一个Docker映像,我们将使用-t进行标记,因此它具有友好的名称。

docker build -t friendlyhello .

你的built image在哪里? 它在您机器的本地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,使得正确的URLhttp:// localhost:4000。 去那里,你会看到“Hello World”文本,容器ID和Redis错误消息。

注意:4000:80的端口重新映射是为了展示Docker文件中EXPOSE之间的区别,以及使用docker run -p发布的内容。 在后面的步骤中,我们将主机上的端口80映射到容器中的端口80,并使用http:// localhost。

在您的终端中点击CTRL + C退出。
现在让我们在后台运行应用程序,在分离模式下:

docker run -d -p 4000:80 friendlyhello

您的应用程序将获得长容器ID,然后被踢回您的终端。 您的容器在后台运行。 您还可以使用docker ps查看缩写容器ID(并且在运行命令时可以互换):

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

您会看到CONTAINER IDhttp:// localhost:4000上的内容相符。

现在使用docker stop来结束进程,使用CONTAINER ID,像这样:

docker stop 1fa4ab2cf395

分享您的图像

为了演示我们刚刚创建的可移植性,让我们上传我们的构建并在其他地方运行它。 毕竟,您需要学习如何推动注册管理机构实现集装箱的部署。

注册表是存储库的集合,存储库是图像集合,类似于GitHub存储库,代码已经被构建。 注册表上的帐户可以创建许多存储库。 默认情况下,docker CLI已预先配置为使用Docker的公用注册表。

注意:我们将使用Docker的公共注册表,因为它是免费的和预配置的,但有很多公共选择,您甚至可以使用Docker Trusted Registry设置您自己的私人注册表。

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

登录您的本地机器:

docker login

现在,发布您的图像。 将本地映像与注册表上的存储库关联的符号是
username / repository:tag。 标签是可选的,但建议; 这是注册表用于给Docker映像一个版本的机制。 所以,把所有的一切,输入你的用户名,和repo和标签名称,所以你现有的图像将上传到您想要的目的地:

docker tag friendlyhello username/repository:tag

上传您的标记图片:

docker push username/repository:tag

一旦完成,此上传的结果是公开的。 从现在开始,您可以使用docker运行并运行您的应用程序在任何机器上使用此命令:

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

注意:如果不指定这些命令的:tag部分,则在构建和运行映像时,将会假定:latest的标签。

无论在哪里运行docker,它会将您的图像以及Python以及require.txt中的所有依赖项提取出来,并运行您的代码。 它一起在一个整齐的小包裹,主机不需要安装任何东西,但Docker来运行它。

在下一节中,我们将通过在服务中运行此容器来了解如何扩展应用程序。

docker build -t friendlyname            #使用此目录的Dockerfile创建映像
docker run -p 4000:80 friendlyname     #运行“friendlyname”映射端口4000到80
docker run -d -p 4000:80 friendlyname   #同样的事情,但在分离模式
docker ps                               #查看所有正在运行的容器的列表
docker stop <hash>                      #正常地停止指定的容器
docker ps -a                            #查看所有容器的列表,即使是没有运行的容器
docker kill <hash>                      #强制关闭指定的容器
docker rm <hash>                        #从此机器中删除指定的容器
docker rm $(docker ps -a -q)           #从本机中删除所有容器
docker images -a                        #显示本机上的所有图像
docker rmi <imagename>                  #从本机中删除指定的图像
docker rmi $(docker images -q)         #从本机中删除所有图像
docker login                            #使用Docker凭据登录此CLI会话
docker tag <image> username/repository:tag      #标签<image>上传到注册表
docker push username/repository:tag     #将标记的图像上传到注册表
docker run username/repository:tag      #从注册表运行映像


标签:容器,80,Get,started,app,应用程序,Part,docker,Docker
From: https://blog.51cto.com/u_16152603/6427424

相关文章

  • DjangoUeditor ImportError: No module named ‘widgets’的解决办法
    http://ojdbc.com/djangoueditor-importerror-no-module-named-widgets/最近在学习Django框架,按照网上教程集成DjangoUeditor时,出现错误,错误提示为:fromwidgetsimportUEditorWidget,AdminUEditorWidgetImportError:Nomodulenamed‘widgets’经查发现,DjangoUeditor是基于Pyt......
  • 解决cURL error 60: SSL certificate problem: unable to get local issuer certifica
    转载:报错原因:因为没有配置信任的服务器HTTPS验证。默认情况下,cURL被设为不信任任何CAs,因此浏览器无法通过HTTPs访问你服务器。一、解决方式下载证书1、放到这里来2、修改php.ini文件,去掉前面“;”路径带上""3、openssl这个扩展开启4、记得重启,不然不生效......
  • Git 的SSL certificate problem: unable to get local issuer certificate问题
    D:\temp>gitclonehttps://github.com/xxxxxx/yyyyyy.gitCloninginto'yyyyyy'...fatal:unabletoaccess'https://github.com/xxxxxx/yyyyyy.git/':SSLcertificateproblem:unabletogetlocalissuercertificate处理方法:D:\temp>gitco......
  • 算法学习day44动态规划part06-518、377
    packageLeetCode.DPpart06;/***518.零钱兑换II*给你一个整数数组coins表示不同面额的硬币,另给一个整数amount表示总金额。*请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回0。*假设每一种面额的硬币有无限个。*题目数......
  • 算法学习day45动态规划part07-322、279
    packageLeetCode.DPpart07;/***322.零钱兑换*给你一个整数数组coins,表示不同面额的硬币;以及一个整数amount,表示总金额。*计算并返回可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回-1。*你可以认为每种硬币的数量是无限的......
  • 算法学习day46动态规划part08-139
    packageLeetCode.DPpart08;importjava.util.HashSet;importjava.util.List;/***139.单词拆分*给你一个字符串s和一个字符串列表wordDict作为字典。请你判断是否可以利用字典中出现的单词拼接出s。*注意:不要求字典中出现的单词全部都使用,并且字典中的单词......
  • 算法学习day48动态规划part09-377、213、198
    packageLeetCode.DPpart09;/***377.组合总和Ⅳ*给你一个由不同整数组成的数组nums,和一个目标整数target。请你从nums中找出并返回总和为target的元素组合的个数。*题目数据保证答案符合32位整数范围。*示例:*输入:nums=[1,2,3],target=4*输......
  • 算法学习day42动态规划part04-416
    packageLeetCode.DPpart04;/***416.分割等和子集*给你一个只包含正整数的非空数组nums。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。*示例:*输入:nums=[1,5,11,5]*输出:true*解释:数组可以分割成[1,5,5]和[11]。**/......
  • 算法学习day43动态规划part05-1049、474、494
    packageLeetCode.DPpart05;/***1049.最后一块石头的重量II*有一堆石头,用整数数组stones表示。其中stones[i]表示第i块石头的重量。*每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为x和y,且x<=y。那么粉碎的可能结果如下:*如果x=......
  • QT 中的QTableWidget
     ......