Docker 基础内容

一、核心概念

用通俗的蛋糕制作类比,快速理解 Docker 三大核心基础概念:

  • Dockerfile:蛋糕的配方,详细罗列所需材料、制作步骤,是构建镜像的核心配置文件。

  • 镜像(Image):按照配方制作完成的半成品蛋糕,可无限复制,每一份副本完全一致,固化了运行环境、依赖、配置等所有内容。

  • 容器(Container):基于半成品蛋糕(镜像)烘焙而成的可食用成品,是真正运行服务的实例。可基于同一镜像创建多个独立容器,容器之间相互隔离、互不干扰,也可自定义配置差异化参数。

从 DockerHub 拉取镜像并运行容器的完整流程:

  1. 镜像维护者编写 Dockerfile(配方),构建生成镜像(半成品蛋糕);

  2. 用户从镜像仓库拉取镜像到本地;

  3. 基于本地镜像创建并运行容器(烘焙成品),启动服务;

  4. 日常操作中,创建容器运行容器通常合并为一步执行。

补充:**层(Layers)缓存(Cache)**为进阶知识点,初期无需掌握,后续学习镜像构建、推送时可深入了解。

二、容器创建与运行

本节提供终端标准命令,同时适配 Docker Desktop 可视化操作逻辑(桌面版界面直观,仅适合入门体验,生产环境优先使用终端命令)。

2.1 拉取镜像

从镜像仓库拉取指定镜像到本地,默认仓库为 DockerHub。

终端通用命令

plain
docker pull 仓库地址/命名空间/镜像名称:标签

参数说明

  • 仓库地址:省略时默认从 DockerHub 拉取;私有仓库必须填写完整地址。

  • 命名空间:区分个人/组织镜像,如 ubuntu/mysqlubuntu 为命名空间;省略时默认拉取官方镜像。

  • 镜像名称:需要拉取的目标镜像名。

  • 标签:镜像版本标识,省略时默认 latest(最新版本)。

补充:docker pull 非必需前置操作,执行 docker run 时,若本地无对应镜像,Docker 会自动远程拉取。

2.2 创建并运行容器

镜像拉取完成后,通过 docker run 一次性完成容器创建、配置与启动。

实操示例命令(MySQL 容器)

plain
# 适配教程的完整运行命令docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:latest

通用语法

plain
docker run [选项参数] 仓库地址/命名空间/镜像名称:标签 [命令行] [命令行参数]

核心选项参数详解

  • --name:自定义容器名称,全局唯一,推荐「镜像名_版本号」命名格式。

  • -p:端口映射,格式 宿主机端口:容器端口,实现宿主机访问容器内部服务,未配置则仅容器内部可访问服务。

  • -e:设置容器环境变量,用于初始化服务配置(如 MySQL 初始密码),不同镜像支持的环境变量不同。

  • -v:目录/数据卷挂载,用于数据持久化、宿主机与容器文件互通。

  • -d:后台运行容器,脱离终端持续运行服务。

补充:命令行与命令行参数为可选配置,用于容器启动时执行自定义指令,日常部署可省略。

2.3 容器与镜像常用命令

docker run 仅用于新建并启动容器,已有容器的启停、删除等操作使用以下专属命令:

plain
# 列出所有容器(包含停止状态)docker ps -a# 列出本地所有镜像docker image lsdocker images# 启动已存在的容器docker start 容器名称/容器ID# 正常停止容器docker stop 容器名称/容器ID# 强制停止容器(紧急场景使用)docker kill 容器名称/容器ID# 重启容器docker restart 容器名称/容器ID# 删除容器(需先停止容器)docker rm 容器名称/容器ID# 删除镜像(需先删除依赖该镜像的容器)docker rmi 镜像名称/镜像ID

三、目录挂载

3.1 挂载解决的核心问题

  • 容器删除后,内部数据会全部丢失,无法持久化;

  • 宿主机与容器、容器与容器之间文件传输繁琐;

  • 多容器共享数据场景无法实现。

3.2 三种挂载方式

  • bind mount(绑定挂载):将宿主机指定目录直接映射到容器目录,双向实时同步文件,适合代码、配置文件等频繁变动的场景。

  • volume(数据卷挂载):Docker 全权管理的专属存储目录,存放在宿主机系统目录,官方推荐,适合数据库数据等无需手动干预的持久化数据。

  • tmpfs mount(临时挂载):数据存储在宿主机内存中,重启即清空,仅用于存放临时文件,不支持多容器共享。

3.3 实操挂载命令

以 MySQL 容器为例,同时配置数据卷挂载与目录绑定挂载:

plain
docker run -d --name mysql_8.3.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v=mysql_volume:/var/lib/mysql -v D:\mount:/pc_mount mysql:latest

挂载解析

  • -v=mysql_volume:/var/lib/mysql:数据卷挂载,命名 mysql_volume,持久化 MySQL 数据,容器删除后数据卷保留;

  • -v D:\mount:/pc_mount:绑定挂载,宿主机D:\mount 目录与容器 /pc_mount 目录双向同步,容器无对应目录则自动创建。

补充:未手动命名的 volume 为匿名数据卷,容器删除后匿名卷会同步删除,无法持久化数据。

四、数据库数据迁移

4.1 端口冲突迁移方案

本地宿主机 MySQL 与容器 MySQL 端口均为 3306 会产生冲突,且容器创建后端口无法修改,通过数据卷复用实现无冲突迁移:

  1. 停止 3306 端口的原有 MySQL 容器;

  2. 新建临时 MySQL 容器,修改端口为未占用端口(如 3305),复用原有命名数据卷

  3. 通过 Navicat 迁移新旧数据库数据;

  4. 删除临时 3305 端口容器,重启原 3306 端口容器,完成数据迁移。

4.2 大文件命令行导入导出

大数据量 SQL 文件迁移,Navicat 性能不足,可通过挂载目录命令行操作:

数据导入步骤

  1. 将 SQL 文件放入宿主机挂载目录(示例:D:\mount);

  2. 进入容器终端:

plain
docker exec -it mysql_8.3.0 bash
  1. 登录 MySQL 并执行导入:
plain
mysql -u root -prootuse test-base;source /pc_mount/001.sql;

数据导出逻辑一致,将文件导出至容器挂载目录,即可在宿主机直接获取文件。

五、Docker 虚拟网络

每个容器默认独立网络环境、相互隔离。除端口映射外,可通过 Docker 虚拟网络实现容器间内网互通,无需暴露端口到宿主机,安全性更高。

5.1 查看网络列表

plain
docker network ls

Docker 默认内置三种网络驱动,适配不同场景:

  • Bridge(默认):容器独立网络空间,可内网互通、访问外网,支持端口映射对外提供服务,为最常用网络模式。

  • Host:容器共享宿主机网络,无需端口映射,直接使用宿主机端口,性能最优,失去网络隔离性。

  • None:禁用所有网络接口,仅保留本地回环,完全隔离,无外网访问能力。

5.2 自定义网络与容器互通

实操命令

plain
# 创建自定义虚拟网络docker network create test_net# 在自定义网络中创建无端口映射的 Redis 容器docker run --name redis_temp --network=test_net -d redis:latest# 创建带端口映射的 Redis 可视化容器,加入同一网络docker run --name redisinsight -p 8001:8001 --network test_net -d redislabs/redisinsight:latest

互通原理:Docker 内置 DNS 服务,容器名称即为内网域名,同一网络内可直接通过容器名通信,无需配置 IP。

补充:已创建的容器可追加接入指定网络:

plain
docker network connect 网络名称 容器名称

六、实用使用技巧

6.1 查看镜像/软件真实版本

latest 标签无明确版本信息,可通过以下方式查询:

方式一:容器内查询(精准)

plain
docker exec mysql_8.3.0 mysql -V

方式二:镜像详情查询(高效)

plain
docker inspect mysql:latest

通过镜像内置环境变量,快速识别版本信息,无需启动容器。

6.2 保持容器持续运行

Ubuntu 等基础镜像容器启动后会立即退出(无持续前台进程),通过交互式参数保持容器常驻:

plain
docker run -it --name ubuntu_22.04 ubuntu:latest
  • -i:开启标准输入,支持用户交互;

  • -t:分配虚拟终端,维持容器前台进程,避免自动退出。

七、镜像构建与推送

7.1 Dockerfile 常用核心指令

  • FROM:指定基础镜像,所有操作基于该镜像执行。

  • WORKDIR:设置容器工作目录,后续命令默认在该目录执行。

  • COPY:复制本地文件到镜像,仅复制普通文件/目录。

  • ADD:高级复制,支持本地文件、远程文件,自动解压 tar 压缩包。

  • RUN:镜像构建阶段执行命令(安装依赖、配置环境等)。

  • CMD:容器默认启动命令,可被 docker run 命令行参数覆盖。

  • ENTRYPOINT:容器固定启动命令,不会被运行参数覆盖,适合固定服务启动逻辑。

  • EXPOSE:声明容器对外开放端口,仅为标识,不主动开启端口映射。

7.2 普通镜像构建(Java 项目示例)

适用于本地已完成项目打包的场景:

plain
# 使用JDK17基础镜像FROM openjdk:17-jdk-slim# 设置工作目录WORKDIR /app# 复制打包后的jar包到镜像COPY target/output-demo.jar app.jar# 配置容器启动指令ENTRYPOINT ["java", "-jar", "app.jar"]# 声明服务端口EXPOSE 8080

7.3 多阶段构建镜像

无需本地安装编译环境,在镜像内完成项目打包构建,精简最终镜像体积:

plain
# 第一阶段:构建阶段(打包项目)FROM maven:3.8.5-openjdk-17-slim AS buildWORKDIR /appADD . .# 打包项目(跳过测试可加 -DskipTests=true)RUN mvn clean package# 第二阶段:运行阶段(精简镜像)FROM openjdk:17-jdk-slimWORKDIR /app# 复制第一阶段打包成果COPY --from=build /app/target/output-demo.jar app.jarENTRYPOINT ["java", "-jar", "app.jar"]EXPOSE 8080

原理:多阶段构建会丢弃构建阶段的冗余依赖,仅保留运行所需文件,大幅减小镜像大小。

7.4 镜像构建命令

plain
# 标准构建(默认使用当前目录Dockerfile)docker build -t 仓库地址/命名空间/镜像名:标签 .# 指定Dockerfile文件路径构建docker build -t 仓库地址/命名空间/镜像名:标签 -f /path/myDockerfile .
  • -t:指定镜像名称与标签,本地使用可省略仓库、命名空间;

  • -f:指定自定义 Dockerfile 路径与文件名;

  • .:指定构建上下文目录,为 COPY/ADD 命令的文件查找根目录。

7.5 镜像推送至仓库

plain
# 登录镜像仓库(私有仓库需填写地址,默认DockerHub无需地址)docker login 仓库地址# 推送镜像到仓库docker push 仓库地址/命名空间/镜像名:标签

7.6 镜像层与缓存机制

层(Layers)

Dockerfile 中 RUNCOPYADD 等修改文件系统的指令,都会生成一个独立镜像层。每层仅记录当前改动内容,多层叠加组成完整镜像。

优化原则:尽量合并连续操作指令,避免冗余层增加镜像体积。

plain
# 冗余写法(生成两层,残留无用文件)RUN apt-get install -y software-packageRUN rm -rf /var/lib/apt/lists/*# 优化写法(单层完成操作,无冗余文件)RUN apt-get install -y software-package && rm -rf /var/lib/apt/lists/*

缓存(Cache)

本地已存在的镜像层可全局共享、复用。构建/拉取镜像时,已存在的层无需重复下载、构建,仅更新差异层,大幅提升构建速度、节省带宽与存储空间。

八、Docker Compose 多容器编排

针对多服务项目(如项目+MySQL+Redis),通过 docker-compose.yml 统一配置、一键启停所有容器,无需逐个配置运行。

8.1 三层核心架构

  • 工程(Project):整体项目单元,统一管理所有服务的网络、数据卷资源;

  • 服务(Service):单个独立服务(应用、数据库、缓存等),可配置端口、挂载、依赖等;

  • 容器(Container):服务的运行实例,单个服务可启动多个容器实现集群。

核心特性:同工程下所有服务共享网络,可通过服务名内网互通,容器配置统一、相互隔离。

8.2 完整配置示例

在项目根目录创建 docker-compose.yml

plain
version: '3.8'services:  # 应用服务  app:    image: '仓库地址/命名空间/镜像名称:标签'    ports:      - 8080:8080    volumes:      - ./:/app    # 依赖服务,先启动数据库、缓存再启动应用    depends_on:      - mysqldb      - redisdb    command: ["java", "-jar", "app.jar"]    restart: always  # MySQL数据库服务  mysqldb:    image: mysql:8.0.30    environment:      - MYSQL_ROOT_PASSWORD=root    volumes:      - db_data:/var/lib/mysql  # Redis缓存服务  redisdb:    image: redis:7.2.4    volumes:      - redis_data:/data# 定义全局数据卷volumes:  db_data:  redis_data:

8.3 常用启停命令

plain
# 后台启动所有服务docker compose up -d# 指定自定义配置文件启动docker compose -f 自定义文件名.yml up -d

注意:修改 yml 配置文件后,需重新执行启动命令,配置方可生效。

(注:部分内容可能由 AI 生成)