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

本文是《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 程序。

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

    公告板应用程序运行中
  3. 对公告板容器正常工作感到满意后,可以将其删除:

    docker rm --force board
    

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

相关文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342