type
Post
status
Published
slug
2019/09/22/1569142374417.html
summary
tags
Docker
category
Docker
icon
password
new update day
Property
Oct 22, 2023 01:31 PM
created days
Last edited time
Oct 22, 2023 01:31 PM

1 先决条件

  • 您已经安装了 1.13 或者版本更高的 Docker 应用程序
  • 为您的环境提供快速测试运行,以确保您已全部设置:
docker run hello-world

2 介绍

现在该开始以Docker方式构建应用程序了。我们将从这样一个应用程序的层次结构的底部开始,该应用程序是一个容器,我们将在此页面中进行介绍。在该级别之上是服务,该服务定义了容器在生产中的行为方式,在第3部分中进行了介绍。最后,在顶层是堆栈,定义了第5部分中介绍的所有服务的交互。
  • Stack
  • Services
  • Container (you are here)

3 您的新开发环境

过去,如果您要开始编写Python应用程序,那么首先要做的就是将Python运行时安装到计算机上。但是,这会造成一种情况,您的计算机上的环境必须如此,以便您的应用程序按预期运行;运行您的应用程序的服务器的同上。
使用Docker,您只需获取一个可移植的Python运行时作为映像,而无需安装。然后,您的构建可以在应用程序代码的旁边包含基本的Python映像,以确保您的应用程序,其依赖项和运行时都一起运行。
这些可移植映像由称为 Dockerfile 的东西定义。

4 用Dockerfile定义一个容器

Dockerfile 将定义容器内部环境中发生的事情。在这种环境内虚拟化了对网络接口和磁盘驱动器等资源的访问,该环境与系统的其余部分隔离,因此您必须将端口映射到外部环境,并具体说明那个环境中要“复制”的文件。但是,这样做之后,您可以期望在此 Dockerfile 中定义的应用程序构建无论在任何地方运行都将表现完全相同。

4.1 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 --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"]
Are you behind a proxy server? 代理服务器可以在您的网络应用启动并运行后立即阻止其连接。如果您位于代理服务器后面,请使用ENV命令为您的Dockerfile添加以下行,以指定代理服务器的主机和端口:
# Set proxy server, replace host:port with values for your servers ENV http_proxy host:port ENV https_proxy host:port
在调用pip之前添加这些行,以使安装成功。
这个 Dockerfile 指向了我们尚未创建的几个文件,即 app.pyrequirements.txt 。接下来创建这些。

5 应用本身

再创建两个文件 requirements.txtapp.py,并将它们与 Dockerfile 放在同一文件夹中。这样就完成了我们的应用程序,您可以看到它非常简单。当上述 Dockerfile 内置到映像中时,由于该 DockerfileADD 命令,将显示 app.pyrequirements.txt,并且借助 EXPOSE 命令,可以通过 HTTP 访问 app.py 的输出。

5.1 requirements.txt

Flask Redis

5.2 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设置环境,但是已经有了。

5.3 Build the app

我们准备构建该应用程序。确保您仍在新目录的顶层。 使用 ls 命令应该显示以下内容:
$ ls Dockerfile app.py requirements.txt
现在运行build命令。这将创建一个Docker映像,我们将使用 -t 对其进行标记,给他起一个友好的名字。
docker build -t friendlyhello .
你构建的 images 在哪里呢?它位于计算机的本地 Docker 映像注册表中:
$ docker images REPOSITORY TAG IMAGE ID friendlyhello latest 326387cea398

5.4 Run the app

运行应用,使用 -p 将计算机的端口 4000 映射到容器的已发布端口 80:
docker run -p 4000:80 friendlyhello
您应该在 http://0.0.0.0:80 看到一条消息,指出Python正在为您的应用提供服务。但是该消息是从容器内部发出的,它不知道您已将该容器的端口80映射到4000,从而生成了正确的URL http://localhost:4000
在网络浏览器中转到该URL,以查看网页上提供的显示内容。
notion image
注意:如果您在Windows 7上使用Docker Toolbox,请使用 Docker Machine 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 中的 EXPOSE 内容与使用 docker run -p 发布的内容之间的区别。在后面的步骤中,我们将主机上的端口80映射到容器中的端口80,并使用 http:// localhost
在终端中按 CTRL + C 退出。
在Windows上,明确停止容器在Windows系统上,CTRL + C不会停止容器。因此,首先键入CTRL + C以返回提示(或打开另一个shell),然后键入 docker container ls 列出正在运行的容器,然后键入 docker container stop 容器名称或ID来停止容器。否则,当您尝试在下一步中重新运行容器时,将从守护程序中收到错误响应。
现在,让我们以分离模式在后台运行该应用:
docker run -d -p 4000:80 friendlyhello
您将获得应用程序的长容器ID,然后将其踢回终端。您的容器在后台运行。您还可以看到带有 docker container ls 的缩写容器ID(并且在运行命令时两者可以互换使用):
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED 1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago
您会看到CONTAINER ID与 http:// localhost:4000上的内容匹配。现在使用docker container stop 通过容器ID结束进程,如下所示:
docker container stop 1fa4ab2cf395

5.5 Share your image

为了演示我们刚刚创建的图像的可移植性,让我们上传构建的图像并在其他地方运行它。毕竟,当您要将容器部署到生产环境时,您将需要学习如何推送到注册表。
注册表是存储库的集合,而存储库是图像的集合,类似于GitHub存储库,只是已经构建了代码。注册表上的帐户可以创建许多存储库。 Docker CLI默认使用Docker的公共注册表。
注意:我们将在这里使用Docker的公共注册表是因为它是免费的且已预先配置,但有许多公共选项可供选择,您甚至可以使用Docker Trusted Registry设置自己的私有注册表。

5.5.1 Log in with your Docker ID

如果您没有Docker帐户,请在https://cloud.docker.com/上注册一个。记下您的用户名。
登录到本地计算机上的Docker公共注册表。
$ docker login

5.5.2 Tag the image

用于将本地映像与注册表上的存储库关联的表示法是 username/repository:tag。该标签是可选的,但值得推荐,因为它是注册管理机构用来给Docker映像提供版本的机制。给存储库命名并为上下文标记有意义的名称,例如 get-started:part2。这会将 get-started 存储库中,并将其标记为 part2
现在,将它们放在一起以标记图像。使用您的用户名,存储库和标签名称运行 docker tag image,以便该图像将上传到您所需的目的地。该命令的语法为:
docker tag image username/repository:tag
For example:
docker tag friendlyhello john/get-started:part2
运行 docker images 以查看新标记的图像。(您也可以使用 docker images 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 ...

5.5.3 Publish the image

将您标记的图像上传到存储库:
docker push username/repository:tag
完成后,此上载的结果将公开提供。如果登录到 Docker 中心,您将看到新映像及其拉取命令。

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

从现在开始,您可以使用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)
无论docker run在何处执行,它都会将您的映像以及Python和所有来自requirements.txt的依赖项拉出,并运行您的代码。所有这些都以整齐的小包装一起运送,并且主机无需安装任何东西即可运行,Docker除外。

6 第二部分总结

仅此页而已。在下一节中,我们将学习如何通过在服务中运行此容器来扩展应用程序。
仅此页而已。在下一节中,我们将学习如何通过在服务中运行此容器来扩展应用程序。

7 总结和备忘单(可选)

这是此页面上的基本Docker命令的列表,以及一些相关的命令(如果您想在继续之前进行一些探索)。
docker build -t friendlyname . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyname # Run "friendlyname" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyname # Same thing, but in detached mode docker container ls # List all running containers docker container ls -a # List all containers, even those not running docker container stop <hash> # Gracefully stop the specified container docker container kill <hash> # Force shutdown of the specified container docker container rm <hash> # Remove specified container from this machine docker container rm $(docker container ls -a -q) # Remove all containers docker image ls -a # List all images on this machine docker image rm <image id> # Remove specified image from this machine docker image rm $(docker image ls -a -q) # Remove all images from this machine docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry
 
欢迎加入喵星计算机技术研究院,原创技术文章第一时间推送。
notion image
 
Docker 学习第一部分——Orientation and setupcentos7 升级openssh到最新版本(openssh-8.0p1)