二、基于 Dockerfile 构建并运行镜像

用户头像
悟尘
关注
发布于: 2020 年 04 月 30 日

本文是《Docker必知必会系列》第二篇,原文发布于个人博客:悟尘纪

上一篇:Docker必知必会系列(一):Docker 基础入门及架构介绍

构建并运行镜像



要构建一个容器,需要做很多的工作,设置很多的配置,如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么经常被提及的无法重复、镜像构建透明性、体积等问题就都会解决。 这个脚本就是 Dockerfile。



准备 Dockerfile 文件



下载示例项目,请在终端中运行以下命令:



curl -LO https://github.com/dockersamples/node-bulletin-board/archive/master.zip
unzip master.zip
cd node-bulletin-board-master/bulletin-board-app


node-bulletin-board项目是一个简单的公告板应用程序,使用 Node.js 编写。在此示例中,假设您编写了此应用程序,现在正尝试对其进行容器化。



Dockerfile 描述如何为容器组装专用文件系统,并且还可以包含一些元数据,这些元数据描述了如何基于该镜像运行容器。公告板应用程序 Dockerfile 内容如下:



# Use the official image as a parent image.
FROM node:current-slim

# Set the working directory.
WORKDIR /usr/src/app

# Copy the file from your host to your current location.
COPY package.json .

# Run the command inside your image filesystem.
RUN npm install

# Inform Docker that the container is listening on the specified port at runtime.
EXPOSE 8080

# Run the specified command within the container.
CMD [ "npm", "start" ]

# Copy the rest of your app's source code from your host to your image filesystem.
COPY . .


编写 Dockerfile 是容器化应用程序的第一步,这些 Dockerfile 命令是构建镜像的步骤。 这个步骤如下:



  • 使用 FORM 指定基于已经存在的 node:current-slim 基础镜像构建。这是一个由 nodejs 官方构建的镜像。

  • 使用 WORKDIR 指定所有后续操作均从镜像文件系统中的 /usr/src/app 目录中执行(而不是主机的文件系统中)。

  • 将文件 package.json 从主机复制到镜像中的当前位置(.)(复制到 `/usr/src/app/package.json

  • 在镜像文件系统中运行命令 npm install(读取 package.json 以确定并安装应用程序依赖)

  • 将应用的其余源代码从主机复制到镜像文件系统。



这些步骤与在主机上设置和安装应用程序所采取的步骤几乎相同。但是,将它们保存为 Dockerfile 可以使您在可移植的隔离 Docker 镜像中执行相同的操作。



上面的步骤构建了我们镜像的文件系统,但是 Dockerfile 中还有其他几行。



  • CMD 指令在镜像中指定一些元数据,该元数据描述了如何基于该镜像运行容器。在本示例中该图像的容器化过程是 npm start

  • EXPOSE 8080 通知 Docker 该容器在运行时监听 8080 端口。



上面是组织一个简单的 Dockerfile 的方法。始终以 FROM 命令开头,然后按照步骤构建您的私有文件系统,并以任何元数据规范作为结束。 Dockerfile 指令比上面看到的要多。有关完整列表,请参阅 Dockerfile 参考



构建并测试镜像



现在您已经有了一些源代码和一个 Dockerfile,现在该构建您的第一个镜像,并确保从其启动的容器能够按预期工作。让我们构建您的公告板图像:



docker build --tag bulletinboard:1.0 .


您将看到 Docker 逐步完成 Dockerfile 中的每条指令,并逐步构建镜像:



Sending build context to Docker daemon 45.57kB
Step 1/7 : FROM node:current-slim
current-slim: Pulling from library/node
48839397421a: Pull complete
cbb6511d79bf: Pull complete
04ec6202052a: Pull complete
29c5eab4674c: Pull complete
8df5bb5f8d2e: Pull complete
Digest: sha256:c92fad90875a6ce7251c72701f9c88e1e3f3efc2eb1d7d1ffb2184204e4f7d98
Status: Downloaded newer image for node:current-slim
---> 6d9a17519d40
Step 2/7 : WORKDIR /usr/src/app
---> Running in 9dfd5c099558
Removing intermediate container 9dfd5c099558
---> 6062c6d2e488
Step 3/7 : COPY package.json .
---> 2ddc37525da9
Step 4/7 : RUN npm install
---> Running in 6ce3fed8ecd7

> ejs@2.7.4 postinstall /usr/src/app/node_modules/ejs
> node ./postinstall.js

Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)

npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN vue-event-bulletin@1.0.0 No repository field.
npm WARN The package morgan is included as both a dev and production dependency.

added 91 packages from 168 contributors and audited 221 packages in 16.854s
found 0 vulnerabilities

Removing intermediate container 6ce3fed8ecd7
---> 38a27fea6567
Step 5/7 : EXPOSE 8080
---> Running in c7528a178327
Removing intermediate container c7528a178327
---> 97f454f32f95
Step 6/7 : CMD [ "npm", "start" ]
---> Running in 72a6340e3d58
Removing intermediate container 72a6340e3d58
---> 0a90efca7ea9
Step 7/7 : COPY . .
---> 84c4f69e2893
Successfully built 84c4f69e2893
Successfully tagged bulletinboard:1.0


将镜像作为容器运行



  1. 根据您的新镜像启动一个容器:



docker run --publish 8000:8080 --detach --name board bulletinboard:1.0


这里有几个常见的标志:



  • --publish要求 Docker 将主机端口 8000 上传入的流量转发到容器的端口 8080。容器具有自己的专用端口集,因此,如果要从网络访问某个端口,则必须以这种方式将流量转发到该端口。否则,作为默认的安全状态,防火墙规则将阻止所有网络流量到达您的容器。

  • --detach 要求 Docker 在后台运行此容器。

  • --name指定一个名称,您可以使用该名称在后续命令中引用您的容器,在这种情况下为board



还要注意,您没有指定容器要运行的程序。您不必这样做,因为在构建 Dockerfile 时使用了CMD指令。Docker 知道在容器启动时会自动运行npm start 程序。



  1. 在的浏览器中访问您的应用程序localhost:8000,您应该看到公告板应用程序已启动并正在运行。





  1. 对公告板容器正常工作感到满意后,可以将其删除:



docker rm --force board


--force选项将删除正在运行的容器。如果停止容器运行,docker stop board则无需使用--force



相关文章





用户头像

悟尘

关注

产业转型创新实践者,资深区块链专家。 2019.09.05 加入

欢迎访问我的博客:http://lixl.cn

评论

发布
暂无评论
二、基于 Dockerfile 构建并运行镜像