Docker是什么?
Docker是一个开源的容器平台,可以轻松地创建、运行、分享和部署应用。它允许开发人员将应用程序及其所有依赖项(如库、运行时环境、配置文件等)打包到一个称为 Docker 镜像的可移植容器中。这些容器可以在任何支持 Docker 的环境中以相同的方式运行,无需担心环境差异或依赖问题
Docker简介
Docker通过将应用及其依赖打包到一个标准化的容器中,实现了环境一致性和快速部署。容器是轻量级、可移植、自给自足的软件包,可以在任何支持Docker的主机上运行。相比传统的虚拟机,容器启动更快、资源占用更少,非常适合微服务架构和持续集成/持续部署(CI/CD)场景。
Docker的核心组件包括:
- 容器引擎(Docker Engine):用于构建和运行容器的服务。容器引擎是一个用于创建、运行和管理容器的软件。最流行的容器引擎是 Docker,但也有其他选择,如 Containerd、CRI-O 等。容器引擎负责与宿主机的操作系统内核交互,以便在其中创建和管理容器。
- 镜像(Docker Image):应用及其依赖的只读模板。
- 容器(Docker Container):镜像的运行实例。
- Docker Hub:官方的镜像仓库,方便分享和分发镜像。
通过Docker,开发者可以更高效地管理应用生命周期,提高开发、测试和运维的效率。
而一个典型的Docker容器架构包括以下组件:
- 宿主机(Host Machine): 宿主机是运行容器的物理或虚拟计算机。它可以是云服务器、物理服务器或者虚拟机实例。宿主机上安装了容器运行时(如 Docker Engine),负责管理容器的生命周期。
- 容器引擎(Container Engine): 容器引擎是一个用于创建、运行和管理容器的软件。最流行的容器引擎是 Docker,但也有其他选择,如 Containerd、CRI-O 等。容器引擎负责与宿主机的操作系统内核交互,以便在其中创建和管理容器。
- 镜像(Image): 镜像是容器运行时的静态文件,包含了应用程序的代码、运行时环境、系统工具和依赖项。镜像是容器的基础,用于创建容器实例。Docker 镜像通常由 Dockerfile 构建而成,可以通过 Docker Hub 或私有镜像仓库分享和分发。
- 容器(Container): 容器是运行在宿主机上的一个或多个镜像的实例。每个容器都是一个独立的运行环境,包含了应用程序及其所有依赖项,以及所需的配置文件。容器之间是相互隔离的,但可以与宿主机共享资源和网络。
- 容器编排(Container Orchestration): 容器编排是一种自动化和管理容器化应用程序的方法。它涉及到部署、扩展、管理和调度容器的过程,以确保应用程序的高可用性、负载均衡和弹性。常见的容器编排工具包括 Kubernetes、Docker Swarm 等。
- 容器注册中心(Container Registry): 容器注册中心是用于存储、管理和分发容器镜像的中心化服务。它允许开发人员和运维团队共享和获取镜像,以便在不同的环境中部署应用程序。常见的容器注册中心包括 Docker Hub、Harbor、Quay 等。
容器技术的代表性实现包括 Docker、Kubernetes、Podman 等。这些工具使得容器的创建、管理和部署变得更加简单和高效,广泛应用于软件开发、测试、部署和运维等领域。
Docker安装
Docker的安装方式有很多种,这里介绍两种最常用的安装方式:
- Docker Desktop:适用于Windows和MacOS系统,安装后直接运行Docker Desktop即可。
- Docker Engine:适用于Linux系统,需要手动安装Docker Engine和Docker Compose。
注意:Docker Desktop和Docker Engine安装方式不同,但安装完成后的配置和操作方式相同。
- 安装Docker Desktop
- 下载Docker Desktop安装包,并运行安装程序。下载地址

- 启动Docker Desktop,并等待初始化完成。
- 安装Docker Engine
- 安装依赖包(以在linux的Ubuntu为例):
在 Linux 上安装 Docker 不同的 Linux 发行版可能有不同的包管理工具和安装步骤。下面我将分别介绍在常见的几种 Linux 发行版上安装 Docker 的方法: 在 Ubuntu 上安装 Docker 在 Ubuntu 上安装 Docker 可以通过 apt 包管理器进行,按照以下步骤操作:
1、更新软件包索引:
sudo apt update2、安装所需的软件包,以支持通过 HTTPS 使用 Docker 仓库:
sudo apt install apt-transport-https ca-certificates curl software-properties-common3、添加 Docker 的 GPG 密钥:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -4、添加 Docker 的APTP仓库:
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"5、更新软件包索引,并安装 Docker Engine:
sudo apt update
sudo apt install docker-ce6、验证 Docker 安装是否成功:
sudo docker --versionDocker镜像
Docker镜像是一个只读的模板,包含了应用程序及其依赖项。镜像可以基于其他镜像创建,也可以作为基础镜像使用。Docker Hub 是一个公共的镜像仓库,可以分享和获取镜像。 镜像的创建和运行方式如下:
- 创建镜像:使用Dockerfile创建镜像。Dockerfile是一个文本文件,包含构建镜像所需的指令。 Dockerfile的格式如下:
# 使用 Node.js 18 简洁版本的官方镜像
FROM node:18-alpine
# 设置环境变量
ENV NODE_ENV=production
ENV PORT=3000
# 设置工作目录
WORKDIR /app
# 仅复制依赖文件(提高构建缓存效率)
COPY package*.json ./
# 安装依赖(使用生产依赖)
RUN npm install --production && npm cache clean --force
# 复制剩余代码
COPY . .
# 暴露端口
EXPOSE 3000
# # 健康检查(可选)
# HEALTHCHECK --interval=30s --timeout=10s \
# CMD curl -f http://localhost:3000 || exit 1
# 容器启动命令
CMD ["node", "app.js"]- 构建镜像:使用docker build命令构建镜像。
docker build -t my-app:latest .- 运行镜像:使用docker run命令运行镜像。
docker run -d -p 3000:3000 my-app:latest- 推送镜像:使用docker push命令将镜像推送到Docker Hub。
docker push my-app:latest多层镜像
多层镜像是指一个镜像可以基于其他镜像创建,并添加新的层。这样,创建镜像的效率更高,并且可以复用已有的层。 多层镜像的创建和运行方式如下:
- 创建基础镜像:创建一个基础镜像,包含应用程序所需的基础依赖项。例如,创建一个 Node.js 18 镜像。
- 创建应用程序镜像:基于基础镜像创建应用程序镜像,并添加应用程序代码和依赖项。
- 运行镜像:使用docker run命令运行镜像。
💒 一、Docker 镜像是“一层一层叠起来的积木”
想象你在搭乐高:
第1块:底板(操作系统,比如 Alpine Linux)
第2块:装 Node.js
第3块:放 package.json 第4块:装依赖,运行 npm install
第5块:放你的代码
第6块:写好启动命令
每放一块,就是一个新的层(layer)。 而 Dockerfile 的每一行指令(某些除外)都会创建一个新层。
🔍 二、看你的 Dockerfile 对应多少层?
FROM node:18-alpine # ← 层1:基础镜像(本身已含多层,但对你来说是“第一层起点”)
WORKDIR /app # ← 层2:创建目录(实际可能合并或优化,但逻辑上是一层)
COPY package*.json ./ # ← 层3:复制文件
RUN npm install --production # ← 层4:安装依赖(会生成 node_modules)
COPY . . # ← 层5:复制源码
CMD ["node", "app.js"] # ← 不产生新层(只是元数据)✅ 所以,虽然只有 6 行,但实际构建出的镜像有 4~5 个可存储的层。
你可以用命令验证:
docker build -t my-app .
docker history my-app输出类似:
IMAGE CREATED CREATED BY SIZE
a1b2c3d4 2 mins ago CMD ["node" "app.js"] 0B
e5f6g7h8 2 mins ago COPY . . 10MB
i9j0k1l2 2 mins ago RUN npm install --production 50MB
m3n4o5p6 2 mins ago COPY package*.json ./ 1KB
q7r8s9t0 2 mins ago WORKDIR /app 0B
<base-image> 2 weeks ago /bin/sh -c #(nop) CMD ["node"] ...👉 每一行(除了 FROM 和 CMD/EXPOSE 等元指令)基本都对应一个实际的文件系统变更层。
❓ 三、那为什么叫“多层”而不是“几步”?
因为 Docker 把每一步的结果都存成一个只读快照,像洋葱一样包起来:
如果你下次只改了代码(COPY . . 这一行变了),前面的 npm install 层不会重新执行,直接复用。 这就是“构建缓存”机制,全靠“分层”实现。 如果 Docker 不分层,每次都要从头装系统、装 Node、装依赖……那构建速度会非常慢。
四、总结一句话
“多层镜像”不是指你写了多少行命令,而是指 Docker 把构建过程拆成多个可缓存、可复用的文件系统层。每一层代表一次变更,最终叠加成完整镜像。
所以:
你写的 几行 Dockerfile → 被 Docker 转换成多个层 → 组合成 多层镜像。 “多层”是 Docker 内部的存储和构建机制,不是你手动创建的,而是自动产生的。
什么是 Docker-compose ?
Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。 它使用一个 YAML 文件来配置应用程序的服务,然后使用一个命令来创建并启动所有服务。 Docker Compose 的主要作用是定义和运行多个 Docker 容器,并管理它们之间的依赖关系。 比如说,我现在有一个 Web 应用程序,它需要两个服务:一个数据库和一个 Web 服务器。 Docker Compose 可以将这两个服务定义成一个 YAML 文件,然后使用 docker-compose up 命令启动这两个服务。只要在用到这两个镜像服务的项目内,有docker-compose.yml文件,且运行 Docker Compose 的目录下 Dockerfile 和 docker-compose.yml 文件都在,就可以使用 docker-compose up 命令启动服务。 以下是一个简单的 Docker Compose 示例:
# 指定 Docker Compose 文件格式版本
# 常用版本:'3.8'(推荐),支持大多数功能
version: '3.8'
# 定义所有要启动的服务(容器)
services:
# 服务名称:app(你可以自定义,如 web、api)
app:
# 构建配置:从当前目录的 Dockerfile 构建镜像
build:
context: . # 构建上下文目录(默认当前目录)
dockerfile: Dockerfile # 指定 Dockerfile 文件名(可选)
image: test_image # 构建后镜像名称(可选)或对应镜像文件名
# 自定义容器名称(可选)
# 如果不设置,会自动生成如:project-app-1
container_name: test_api_app # 自定义容器名称
# 暴露端口:将主机端口映射到容器端口
# 格式:主机端口:容器端口
ports:
- "3000:3000" # 主机3000 → 容器3000
# - "80:3000" # 可选:让外部通过80访问(需权限)
# 设置环境变量(等同于 -e)
environment:
NODE_ENV: production # 节点环境
PORT: 3000 # 应用监听端口
DB_HOST: mysql # 数据库主机名(服务名)
DB_PORT: 3306 # 数据库端口
REDIS_HOST: redis # Redis 主机名
REDIS_PORT: 6379 # Redis 端口
# 从文件加载环境变量(推荐用于敏感信息)
# 文件内容:DB_PASSWORD=secret123
env_file:
- .env # 加载根目录的 .env 文件
# 挂载卷(数据持久化或开发热更新)
volumes:
- ./:/app # 开发时:代码热更新(可选)
- /app/node_modules # 防止覆盖容器内的 node_modules
# 启动依赖:确保 db 和 redis 先启动
# ⚠️ 注意:只等容器启动,不等服务就绪!
depends_on:
- mysql
- redis
# 重启策略
# unless-stopped:除非手动停止,否则始终重启
restart: unless-stopped
# 健康检查:Docker 定期检查服务是否正常
# healthcheck:
# test: ["CMD", "curl", "-f", "http://localhost:3000/health"] # 检查健康接口
# interval: 30s # 每30秒检查一次
# timeout: 10s # 超时10秒
# retries: 3 # 失败3次标记为不健康
# start_period: 40s # 启动后40秒内不检查(给应用启动时间)
# 自定义网络(可选,多个服务在同一网络可通信)
networks:
- app-network
# 服务名称:db(PostgreSQL 数据库)
mysql:
image: mysql:8.0 # 使用官方 MySQL 镜像
environment:
MYSQL_ROOT_PASSWORD: rootpass # root 密码(可选)
MYSQL_DATABASE: personalblog_cn # 创建数据库名
MYSQL_USER: devConnect # 用户名
MYSQL_PASSWORD: Zhou20000322. # 密码(生产环境建议用 secrets)
volumes:
- db-data:/var/lib/mysql # 持久化数据
ports:
- "3306:3306" # 映射端口(可选,调试用)
restart: unless-stopped
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "devConnect", "-pZhou20000322."]
interval: 30s
timeout: 10s
retries: 3
networks:
- app-network
# 服务名称:redis(缓存服务)
redis:
image: redis:alpine # 使用轻量 Redis 镜像
command: redis-server --appendonly yes # 开启 AOF 持久化
volumes:
- redis-data:/data # 持久化 Redis 数据
ports:
- "6379:6379" # 映射端口(可选)
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
networks:
- app-network
# 定义命名卷(由 Docker 管理,数据持久化)
# 即使容器删除,数据也不会丢失
volumes:
db-data: # MYSQL 数据卷
redis-data: # Redis 数据卷
# 定义自定义网络
# 所有服务加入同一网络,可通过服务名通信(如 http://db:5432)
networks:
app-network:
driver: bridge # 使用桥接网络(默认)常用命令
Docker
单个镜像一般使用 docker run 命令来启动容器。 运行:
docker run -d -p 3000:3000 --name test_imageDocker Compose
多个镜像使用 docker-compose 命令来启动容器。
运行:
docker-compose up -d
停止:
docker-compose down
删除:
docker-compose rm
删除所有容器:
docker rm $(docker ps -aq)
删除所有镜像:
docker rmi $(docker images -q)
删除所有未使用的镜像:
docker rmi $(docker images -f "dangling=true" -q)
删除所有未使用的网络:
docker network rm $(docker network ls -qf dangling=true)
删除所有未使用的数据卷:
docker volume rm $(docker volume ls -qf dangling=true)