docker Dockerfile创建一个容器,并发布到Docker CLoud

一、定义Dockerfile

创建一个空目录,并在目录中创建dockerfile文件

#创建目录
mkdir /data/docker

#进入目录
cd /data/docker

#创建dockerfile文件
vim Dockerfile

#写入
#使用官方的Python运行时作为父镜像
FROM python:2.7-slim

#设置工作目录
WORKDIR /app

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

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

#对外提供80端口
EXPOSE 80

#设置环境变量
ENV NAME World

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

#创建 requirements.txt 文件
vim requirements.txt

#写入软件列表
Flask
Redis

#创建app.py文件
vim 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本身),我们应该期望在这里使用它的尝试将失败并产生错误消息。

二、构建应用程序

这里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

在网页浏览器中转到该网址,查看在网页上提供的显示内容,包括“Hello World”文本,容器ID和Redis错误消息。

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

$ 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是为了展示你EXPOSE在内部Dockerfile和你publish使用的 内容之间的区别docker run -p。在后面的步骤中,我们将主机上的端口80映射到容器中的端口80并使用http://localhost

CTRL+C在您的终端中点击退出。

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

docker run -d -p 4000:80 friendlyhello

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

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

你会看到CONTAINER ID匹配的是什么http://localhost:4000

现在docker stop用来结束这个过程,用的CONTAINER ID就是这样:

docker stop 1fa4ab2cf395

分享您的图像

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

注册表是存储库的集合,存储库是图像集合,类似于GitHub存储库,代码已经被构建。注册表上的帐户可以创建许多存储库。该dockerCLI使用泊坞窗的公共注册表默认情况下。

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

使用您的Docker ID登录

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

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

docker login

标记图像

将本地映像与注册表上的存储库关联的符号是 username/repository:tag。标签是可选的,但建议,因为它是注册表使Dockport映像版本的机制。给存储库并为上下文标记有意义的名称,例如 get-started:part1。这将把图像放在get-started存储库中并将其标记为part1

现在,把它放在一起来标记图像。运行docker tag image您的用户名,存储库和标签名称,以便映像将上传到您想要的目的地。该命令的语法是:

docker tag image username/repository:tag

例如:

docker tag friendlyhello john/get-started:part1

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

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
john/get-started         part1               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:part1
Unable to find image 'john/get-started:part1' locally
part1: Pulling from orangesnap/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:part1
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

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

无论docker run执行什么,它都会将您的图像,以及Python和所有依赖关系从requirements.txt您的代码中提取出来,并运行您的代码。它一起在一个整齐的小包裹,主机不需要安装任何东西,但Docker来运行它。

以下是该页面的基本Docker命令的列表,如果您想在浏览之前先探索一些相关的命令。

docker build -t friendlyname . # 使用此目录的Dockerfile创建映像
docker run -p 4000:80 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 # Tag <image> 用于上传到注册表
docker push username/repository:tag # 将标记的映像上传到注册表
docker run username/repository:tag # 从注册表运行映像

发表评论

电子邮件地址不会被公开。 必填项已用*标注