镜像好比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
里看到并执行。反之,容器内生成的文件(比如缓存)也会保存在宿主机上,即使容器重启或删除,代码和生成的文件都不会丢失。