概览
欢迎!非常兴奋你想要学习Docker。
这个教程一步步的指导你如何开始使用Docker,这个教程中,你将学习和做下面的事情:
- 构建一个镜像并运行为容器。
- 使用Docker Hub分离镜像。
- 使用带有数据库多个容器部署Docker应用程序。
- 使用Docker Compose运行应用程序。
在你上手这部分教程之前,你应该先学习镜像和容器。
什么是容器
简单来说,容器就是一个沙盒,运行在你的机器上,和宿主机上其他所有进程隔离。这种隔离利用了kernel namespaces and cgroups,一种已经在Linux中使用了很长时间的功能。Docker使用这种功能易于使用。总结下,一个容器:
- 一个运行的镜像实例。你可以使用Docker API或CLI(command-line interface)创建、启动、停止、移动或删除一个容器。
- 可以运行在本地机器、虚拟机或部署到云上。
- 可移植(可以运行在任何操作系统上)。
- 和其他容器隔离,运行它自己的软件、二进制文件和配置。
什么是镜像
当运行一个容器,它使用的是隔离的文件系统。这个自定义的文件系统是容器的镜像提供的。由于这个镜像包含容器的文件系统,它必须包含运行一个应用所需的一切——所有依赖,配置、脚本、二进制文件等。这个镜像也包含容器的其他配置,比如环境变量,默认运行的命令和其他元数据。
在这个教程中,你将更加深入的学习镜像,包含的主题有层、最佳实践等。
容器化一个应用
下面的教程,你将使用一个Node.js编写的待办列表管理器软件。如果你不熟悉Node.js,不用担心。这个教程不需要任务JavaScript经验。
为完成这个教程,你需要以下内容:
- 本地运行的Docker。若没有,本专栏前端有专门的介绍,或参照download and install Docker。
- 一个Git客户端。
- IDE或文本编辑器来编辑文件。Docker推荐使用Visual Studio Code。
- 对镜像和容器有概念上的理解。
获取APP
在运行这个程序之前,你需要将程序源码下载到你的电脑上。
- 使用下面的命令克隆getting-started repository
$ git clone https://github.com/docker/getting-started.git
- 查看克隆仓库的内容。在getting-started/app目录下,你会看到package.json和两个子目录(src和spec)
构建APP的容器镜像
为了构建镜像,你需要用到Dockerfile。Dockerfile是一个简单文本文件,没有扩展名,包含一组脚本指令。Docker使用这个脚本构建镜像。
- 在app目录下,package.json同位置,创建一个Dockerfile名称的文件。根据你的操作系统各类,你可以使用下面的命令来创建这个Dockerfile。
Mac / Linux
在终端,运行下面的命令列表。
修改app目录。使用你本地getting-started/app所在目录替换下面命令中的/path/to/app。
cd /path/to/app
创建一个空的、名称Dockerfile的文件。
touch Dockerfile
Windows
在Windows命令提示符中,运行下面的命令行。
修改app目录:使用你本地getting-started/app所在目录替换下面命令中的/path/to/app。
cd \path\to\app
创建一个空的、名称Dockerfile的文件。
type nul > Dockerfile
- 使用文本编辑器或代码编辑器,将下面的内容添加到Dockerfile中。
# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000
- 使用下面的命令构建镜像。
在终端内,修改getting-started/app目录:使用你本地getting-started/app所在目录替换下面命令行中的/path/to/app。
cd /path/to/app
构建镜像:
docker build -t getting-started .
docker build
命令使用Dockerfile构建一个新的镜像。也许你已经注意到Docker下载了很多层。这是因为你要求构建器从node:18-alpine镜像开始。但,因为你本地机器上没有这个镜像,Docker需要下载它。
Docker下载这个镜像后,Dockerfile中的指令拷贝你的应用程序,并且使用yarn安装程序的依赖。CMD指令指定从该镜像启动一个容器时,默认要执行的命令。
最后,-t给镜像打上标签,可以简单的认为给这个最终的镜像赋一个可读的名称。因为你给这个镜像命名为getting-started,当你运行一个容器时你可以引用这个镜像。
docker build
命令后台的 . 告诉Docker从当前目录下寻找Dockerfile
启动一个app容器
现在你有了一个镜像,你可以在一个容器中运行这个程序。为完成这个操作,你会用到docker run命令。
- 使用docker run命令启动容器,指定你刚才创建的镜像的名称。
docker run -dp 3000:3000 getting-started
使用-d标签,在后台运行新的容器。使用-p映射宿主机的3000端口到容器的3000端口,没有端口映射,你将无法访问该应用。
- 几秒后,打开你的浏览器,输入http://localhost:3000,你就会看到你的APP。
- 随意添加一到两个条目,确认该APP按照你的期望工作。你可以将条目标记为完成,并删除。前端成功的将条目存储在后端。
到目前为止,你已经运行了一个待办列表管理器,有几个条目,均有你自己创建。
如果你快速查看下你的容器,你至少会看到一个容器在运行,使用的是getting-started镜像和3000端口。为了看你的容器,你可以使用CLI或Docker桌面图形接口。
命令行
在终端运行docker ps
命令,列出你的容器。
docker ps
出现下面的内容
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
58853bcb4c8e docker/getting-started "/docker-entrypoint.…" 9 months ago Up 7 hours 0.0.0.0:8080->80/tcp getstarted
Docker桌面
在Docker桌面,选择Containers查看容器列表。
更新应用程序
在第2章节,你使一个待办应用软件容器化,在这部分,你会更新这个应用和其镜像。你也会学到如何停止、删除一个容器。
更新源码
在下面的步骤中,当待办列表中没有条目时,你会将显示的“无内容”修改为“你还没有待办事项!在上面添加一个”。
- 在src/static/js/app.js文件中,使用新的空内容修改第56行。
...
- <p className="text-center">No items yet! Add one above!</p>
+ <p className="text-center">You have no todo items yet! Add one above!</p>
...
- 构建你更新版本后的镜像,使用和在第2章节中同样的docker build命令:
docker build -t getting-started .
- 使用更新后的代码启动一个新的容器。
docker run -dp 3000:3000 getting-started
你也许会看到下面的异常(IDS 会不一样)
docker: Error response from daemon: driver failed programming external connectivity on endpoint laughing_burnell
(aa23232ca4ddfebarte794dffb36hfr125708e34d34d7f4532eaf16324aabde9dd): Bind for 0.0.0.0:3000 failed: port is already allocated.
异常出现的原因是老的容器在运行时,你不能启动一个新的容器。原因是老的容器已经在使用主机的3000端口,在这个机器上只能有一个进程(包括容器)监听指定的端口。为修复这个问题,你需要删除老的容器。
删除老的容器
为了删除一个容器,你首选要做的是先停止它。它一旦停止,你就可以删除它。你可以通过CLI或Docker桌面图形化接口删除。选择你最舒服的方式。
使用CLI删除容器
- 使用
docker ps
获取待删除的容器id。
docker ps
- 使用
docker stop
停止容器。使用docker ps
输出的ID替换。
docker stop <the container-id>
- 一旦容器停止,你就可以使用
docker rm
命令删除它。
docker rm <the-container-id>
在
docker rm
命令中添加force
标签,可以同一个命令同时停止、删除一个容器。比如:docker rm -f <the-container-id>
启动更新后的APP容器
- 现在使用
docker run
命令启动更新后的APP容器。
docker run -dp 3000:3000 getting-started
- 刷新浏览器http://localhost:3000,你会看到更新后帮助文本