Docker 的三核心是镜像与容器和数据卷

镜像好比PHP安装包,容器是运行中的PHP进程,数据卷就是网站目录。端口映射让Nginx能连到容器,这三个核心缺一不可。

得用最直白的比喻:镜像是食谱,容器是炒菜的过程,数据卷是共享的食材篮。这样用户能瞬间理解静态和动态的区别。最后要强调三者如何组合使用,毕竟用户最终是要解决实际问题,不是背概念。

Docker 的核心可以概括为三大概念,它们构成了容器化技术的基石。几乎所有 Docker 操作都是围绕这三个核心展开的。

这三大核心是:镜像(Image)容器(Container) 和 数据卷(Volume)

1. 镜像 (Image)

镜像是一个只读的模板,它包含了创建 Docker 容器所需的所有文件和依赖项

  • 比喻
    • 镜像是 软件的安装包(比如 Windows.iso 或 Software.dmg)。
    • 镜像是 巧克力的模具 或者 糕点的食谱
    • 镜像是 虚拟机的快照.vmx 文件)。
  • 特点
    • 只读的:镜像一旦创建就无法更改,保证了环境的一致性。
    • 分层的:镜像由一系列层(layer)组成,每一层代表 Dockerfile 中的一条指令。这种分层结构使得镜像非常轻量和高效。
    • 静态的:它躺在你的硬盘里,本身不执行任何操作。
  • 相关命令
    • docker pull nginx:从仓库拉取(下载)镜像。
    • docker images:列出本地已下载的镜像。
    • docker build -t my-app .:根据 Dockerfile 构建自己的镜像。
    • docker rmi <image_id>:删除一个本地镜像。

举例
php:8.2-fpm 就是一个官方镜像。它里面包含了 Debian 操作系统、PHP 8.2 解释器、PHP-FPM 程序、Composer 以及其他一些基础的 Linux 工具。你下载它,就得到了一个可以随时用来创建 PHP 环境的模板。

2. 容器 (Container)

容器是镜像的一个运行实例。你可以把它理解为一个轻量级、隔离的进程。

  • 比喻
    • 容器是 根据安装包安装好并正在运行的软件(比如正在运行的 Chrome 浏览器)。
    • 容器是 用模具压出来的巧克力
    • 容器是 根据食谱做出来的蛋糕
    • 容器是 从快照启动起来的虚拟机
  • 特点
    • 可写的:容器在镜像的只读层之上,增加了一个可写的薄薄顶层(容器层)。所有修改都发生在这里。
    • 隔离的:每个容器拥有自己独立的进程空间、网络配置、文件系统(通过挂载点与主机共享部分内容)
    • 临时的:容器可以被轻易地启动、停止、删除和替换。容器的生命周期通常与它内部运行的进程相同。
  • 相关命令
    • docker run -d --name my-nginx nginx:latest:从镜像创建并启动一个容器(-d 表示后台运行)。
    • docker ps:查看正在运行的容器。
    • docker stop my-nginx:停止一个容器。
    • docker start my-nginx:启动一个已停止的容器。
    • docker rm my-nginx:删除一个容器。

举例
当你执行 docker run -d --name php82 php:8.2-fpm 时,Docker 就基于 php:8.2-fpm 这个镜像创建了一个名为php82 的容器。这个容器里正在运行着 PHP-FPM 的进程。你可以同时运行 10 个基于同一个 php:8.2-fpm 镜像的容器,它们彼此隔离,互不影响。

创建容器

root@lavm-od61ss3meu:~# docker run -d --name php82 php:8.2-fpm
87ea29b44bd012c341da83f8f218ef45847f6937ad34b00f2088ac0076491269

容器列表

root@lavm-od61ss3meu:~# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS      NAMES
87ea29b44bd0   php:8.2-fpm   "docker-php-entrypoi…"   13 seconds ago   Up 12 seconds   9000/tcp   php82

基于同一个 php:8.2-fpm 镜像创建几个容器

root@lavm-od61ss3meu:~# docker run -d --name php82-1  php:8.2-fpm
67ca4c5fe5824e1878f7035b10e200a8f9518d184f137ecac44836242cacbbdd
root@lavm-od61ss3meu:~# docker run -d --name php82-2  php:8.2-fpm
662d7243e9dcafa36c647fd244088ec444bf911a38766520bdd9fe6e04161997

root@lavm-od61ss3meu:~# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED          STATUS          PORTS      NAMES
662d7243e9dc   php:8.2-fpm   "docker-php-entrypoi…"   4 seconds ago    Up 3 seconds    9000/tcp   php82-2
67ca4c5fe582   php:8.2-fpm   "docker-php-entrypoi…"   11 seconds ago   Up 10 seconds   9000/tcp   php82-1
87ea29b44bd0   php:8.2-fpm   "docker-php-entrypoi…"   2 minutes ago    Up 2 minutes    9000/tcp   php82

3. 数据卷 (Volume)

数据卷是用于持久化容器产生数据的机制,也是容器与宿主机之间共享数据的首选方式。

  • 比喻
    • 数据卷是 容器的外接移动硬盘 或 U盘
    • 数据卷是 容器和主机之间的共享文件夹
  • 为什么需要它?
    • 因为容器的文件系统是临时的。一旦容器被删除,它产生的所有数据(如日志、数据库文件、用户上传的图片)也会随之消失。
    • 数据卷的存在使得数据独立于容器本身的生命周期,即使容器被删除了,数据卷里的数据依然安全地保存在宿主机上。
  • 相关命令
    • docker run -v /host/path:/container/path ...:将宿主机的目录挂载到容器内(绑定挂载)。
    • docker run -v volume_name:/container/path ...:使用一个命名的数据卷挂载到容器内。
    • docker volume ls:列出所有数据卷。
    • docker volume create my_volume:创建一个命名的数据卷。
    • docker volume inspect my_volume:查看数据卷的详细信息(比如它在宿主机上的实际存储路径)。

举例
这是我们之前讨论的关键!

docker run -d --name my_php \
  -v /www/wwwroot:/var/www/html \  # 核心!挂载数据卷
  php:8.2-fpm
  • -v /www/wwwroot:/var/www/html:这行命令创建了一个绑定挂载的数据卷。
  • 宿主机的 /www/wwwroot 目录(宝塔的网站根目录)被挂载到了 容器内的 /var/www/html 目录(PHP-FPM 的网站根目录)。
  • 这样,你在宝塔面板里上传代码到 /www/wwwroot,容器里的 PHP 立刻就能在 /var/www/html 里看到并执行。反之,容器内生成的文件(比如缓存)也会保存在宿主机上,即使容器重启或删除,代码和生成的文件都不会丢失。

发表评论