单元五 Docker 发布与部署 · 第 18 课

Docker 是什么

“在我电脑上明明能跑”是程序员最常说的一句话。Docker 把程序和它需要的一切打包在一起,在哪里都能一模一样地运行。

本课目标

  • 理解镜像、容器、仓库、Dockerfile 四个概念。
  • 在云主机上安装 Docker。
  • 运行第一个容器,学会几个常用命令。

先懂概念:集装箱

以前海运货物,大小形状五花八门,装卸很麻烦。后来有了标准集装箱:不管里面装的是什么,码头、轮船、卡车都用同一套方式搬运。

Docker 就是软件的集装箱:

概念类比说明
Dockerfile装箱清单一个文本文件,写明从什么基础开始、放进哪些文件、怎么启动
镜像(image)封好的集装箱按清单打包出来的成品,包含程序和它需要的运行环境,只读
容器(container)打开并正在使用的集装箱镜像运行起来的样子,可以启动、停止、删除
仓库(registry)集装箱码头存放和分发镜像的地方,比如 Docker Hub

好处是:

  • 环境一致:镜像里自带 Node.js,服务器上不用另外安装;
  • 易迁移:换一台服务器,拉取同一个镜像就能运行;
  • 易回滚:每个版本是一个镜像,新版本有问题就换回旧镜像。

我们直接在云主机上安装和使用 Docker,不在自己电脑上装。这样能避开 Windows 上的虚拟化设置、公司电脑的安装限制,以及 Mac 和服务器芯片架构不同带来的问题。

跟着做

以下命令都在服务器上运行:ssh ai-server。

1. 安装 Docker

Docker 官方提供了一个安装脚本。先下载下来,而不是直接运行,这是对待安装脚本的好习惯:

curl -fsSL https://get.docker.com -o get-docker.sh
less get-docker.sh

用 less 粗略看一眼(按 q 退出),确认是 Docker 官方的脚本。然后运行:

sudo sh get-docker.sh

等一两分钟。完成后检查:

sudo docker version

能看到 Client 和 Server 两部分的版本信息,就装好了。

2. 不用每次都输入 sudo

把自己加入 docker 用户组:

sudo usermod -aG docker $USER
exit

必须退出再重新登录才会生效:

ssh ai-server

看到服务器的提示符后,再运行:

docker version

这次不加 sudo 也能运行了。

docker 组的成员实际上拥有和管理员差不多的权限。只把你自己加进去,不要随便加别人。

3. 运行第一个容器

docker run --rm hello-world

Docker 会从 Docker Hub 下载 hello-world 镜像,运行它,打印一段欢迎信息后退出。--rm 表示容器退出后自动删除,不留垃圾。

你应该看到

Hello from Docker!
This message shows that your installation appears to be working correctly.

常用命令

命令作用
docker images列出本机的镜像
docker ps列出正在运行的容器;加 -a 包括已停止的
docker run 镜像名用镜像启动一个容器
docker logs 容器名看容器的输出日志
docker stop 容器名停止容器
docker rm 容器名删除已停止的容器
docker image prune清理没有标签、也没有被容器使用的“悬空”镜像,释放磁盘

现在运行 docker images,能看到刚下载的 hello-world。

常见问题

permission denied while trying to connect to the Docker daemon? 还没有加入 docker 组,或者加入后没有重新登录。

下载很慢或失败? 确认服务器是香港地域。内地地域的服务器访问 Docker Hub 经常失败,需要使用云服务商提供的镜像加速,本课程不展开。

Cannot connect to the Docker daemon? Docker 服务没有运行,执行 sudo systemctl start docker。

自检

  • 我能用集装箱的类比解释镜像、容器、仓库、Dockerfile。
  • docker version 不加 sudo 也能运行。
  • docker run --rm hello-world 显示了 Hello from Docker!。