目录

一. Docker基础概念

1.1 Docker是什么

1.2 Docker解决了什么问题

1.3 Docker架构

二. 镜像 (image)

2.1 镜像是什么

2.2 镜像仓库 (Docker Hub)

2.3 常用镜像命令

三. 自定义镜像 (Dockerfile)

3.1 镜像的结构

3.2 Dockerfile是什么

3.3 Dockerfile常用指令

四. 容器(Container)

4.1 容器是什么

4.2 容器与镜像的对比表

4.3 常用容器命令

五. 多容器编排 (Docker Compose)

5.1 Docker Compose是什么

5.2 基本语法

5.3 常用命令

六. 数据卷(Volume)

6.1 数据卷是什么

6.2 数据卷常用命令

6.3 命名卷与绑定挂载

七. 网络(Network)

7.1 Docker网络的作用

7.2 Docker中的网络类型

7.3 网络常用命令

八. RAG 智能问答系统容器化

一. Docker基础概念

1.1 Docker是什么

Docker 是一个用于开发、发布和运行应用程序的开放平台。Docker 提供了在松散隔离的环境中(称为容器)打包和运行应用程序的功能。这种隔离性和安全性可以在给定主机上同时运行多个容器。容器是轻量级的,包含运行应用程序所需的一切,因此无需依赖主机上已安装的内容。您可以在工作时共享容器,并确保与您共享的每个人都能获得相同的容器并以相同的方式工作。

详细信息可参考官方文档: dockerdocs

1.2 Docker解决了什么问题

  • 环境不一致问题: 通过容器镜像封装一切依赖(代码、运行时、库、配置等),“一次构建,到处运行”。

  • 应用部署复杂问题: 镜像打包即部署,部署逻辑自动化;每个容器相互隔离,解决端口冲突、库冲突等;通过版本化镜像,轻松实现升级和回滚。

  • 资源利用率低的问题: 容器是轻量级的,不需要完整操作系统,启动快,占用资源少;在同一台机器上可以运行多个容器,提高资源利用率

  • 持续集成/持续交付(CI/CD)困难: 容器天然适合集成在 CI/CD 流程中;自动构建镜像、运行测试容器、发布新版本;保证发布的一致性和稳定性。

  • 多语言/多架构支持困难: 每个服务一个镜像,互不影响;用 Docker Compose 管理多个容器,方便构建微服务架构。

1.3 Docker架构

Docker 采用客户端-服务器架构。Docker 客户端与 Docker 守护进程通信,后者负责构建、运行和分发 Docker 容器等繁重工作。Docker 客户端和守护进程可以运行在同一系统上,或者您可以将 Docker 客户端连接到远程 Docker 守护进程。Docker 客户端和守护进程使用 REST API、UNIX 套接字或网络接口进行通信。另一个 Docker 客户端是 Docker Compose,它允许您处理由一组容器组成的应用程序。

Docker Architecture diagram

二. 镜像 (image)

2.1 镜像是什么

镜像是一个只读的模板,包含了运行应用所需的一切内容:代码、依赖、运行时、环境变量、配置文件等。可以理解为一份“蓝图”或者“快照”。

2.2 镜像仓库 (Docker Hub)

Docker官方提供了一个专门管理、存储镜像的网站,并对外开放了镜像上传、下载的权利。Docker官方提供了一些基础镜像,然后各大软件公司又在基础镜像基础上,制作了自家软件的镜像,全部都存放在这个网站。这个网站就成了Docker镜像交流的社区:Docker Hub 官网

基本上我们常用的各种软件都能在这个网站上找到,我们甚至可以自己制作镜像上传上去。

2.3 常用镜像命令

命令 作用 示例
docker images 查看本地已有的镜像列表 docker images
docker pull 从远程仓库下载镜像 docker pull nginx:latest
docker build 基于 Dockerfile 构建镜像 docker build -t myapp:1.0 .
docker rmi 删除镜像 docker rmi nginx
docker save 将镜像保存为 tar 文件 docker save -o myapp.tar myapp:1.0
docker load 从 tar 文件加载镜像 docker load -i myapp.tar
docker history 查看镜像构建历史(每层信息) docker history nginx
docker inspect 查看镜像详细元数据(JSON 格式) docker inspect nginx
docker search 搜索镜像仓库中的镜像 docker search redis
docker push 推送镜像到远程仓库(如 Docker Hub) docker push myrepo/myapp:1.0

更多命令可参照官方文档: docker官网命令

三. 自定义镜像 (Dockerfile)

3.1 镜像的结构

Docker 镜像是由多层(layer)组成的,每一层都是一个文件系统变更(比如添加文件、安装软件、设置环境变量等)。

举个简单的镜像结构示意图:

 ┌────────────────────┐
 │ Layer 4: 应用配置   │
 ├────────────────────┤
 │ Layer 3: 应用依赖   │
 ├────────────────────┤
 │ Layer 2: 操作系统包 │
 ├────────────────────┤
 │ Layer 1: 基础系统   │
 └────────────────────┘

MySQL镜像大约的结构(以 mysql:8.0 为例):

层级 内容说明
Layer 1 debian 系统基础层(MySQL 官方以 Debian 为基础)
Layer 2 添加系统工具(如 bash、coreutils)
Layer 3 安装 MySQL 依赖库与用户
Layer 4 安装 MySQL Server 本体(.deb 包)
Layer 5 添加启动脚本、配置等
Layer 6 设置默认环境变量、端口等
Layer 7 设置启动命令(如 mysqld

3.2 Dockerfile是什么

由于制作镜像的过程中,需要逐层处理和打包,比较复杂,所以Docker就提供了自动打包镜像的功能。我们只需要将打包的过程,每一层要做的事情用固定的语法写下来,交给Docker去执行即可。而这种记录镜像结构的文件就称为Dockerfile

其对应的语法可以参考官方文档:Dockerfile官方文档

3.3 Dockerfile常用指令

指令 用途 示例
FROM 指定基础镜像(必须是第一条) FROM python:3.10
RUN 在镜像构建时执行命令(如安装依赖) RUN apt-get update && apt-get install -y curl
CMD 指定容器启动后要执行的命令(可被覆盖) CMD ["python", "app.py"]
ENTRYPOINT 指定入口命令,通常与 CMD 配合 ENTRYPOINT ["docker-entrypoint.sh"]
COPY 将主机文件复制到镜像中 COPY . /app
ADD 类似 COPY,但支持解压 tar/URL 下载 ADD app.tar.gz /app
WORKDIR 设置工作目录(之后命令以此为当前目录) WORKDIR /app
EXPOSE 声明容器要监听的端口(不会自动映射) EXPOSE 8080
ENV 设置环境变量 ENV PORT=8080
VOLUME 声明挂载点(持久化数据) VOLUME ["/data"]
USER 指定运行容器时的用户 USER node
ARG 构建时传参(与 ENV 不同) ARG APP_VERSION=1.0

其对应的语法可以参考官方文档:Dockerfile官网指令

如对于基础练习的exercise1可编写以下的Dockerfile:

 FROM ubuntu:22.04
 ​
 # 更新包索引并安装 nginx 和 curl
 RUN apt-get update && \
     apt-get install -y nginx curl
 ​
 # 创建简单的 HTML 文件
 RUN echo "Hello Docker!" > /var/www/html/index.html
 ​
 # 暴露 80 端口
 EXPOSE 80
 ​
 # 启动 nginx 服务,-g参数表示全局配置,daemon off表示不用以守护进程运行
 CMD ["nginx", "-g", "daemon off;"]

四. 容器(Container)

4.1 容器是什么

容器是基于镜像运行起来的实例,是应用真正运行的环境。容器中包含镜像的内容,并加上一层读写层,允许运行时修改(但不会影响原始镜像)。

4.2 容器与镜像的对比表

比较项 镜像 (Image) 容器 (Container)
定义 应用和环境的静态模板 镜像的运行实例
状态 静态的、只读的 动态的、可读写的
创建方式 通过 Dockerfile 构建或 pull 获得 通过 docker run 从镜像生成
是否可运行 是,是真正运行的应用
生命周期管理 不需要,始终存在 可以启动、停止、删除、重启
类比 面包模具、系统镜像 面包、运行中的程序/虚拟机

4.3 常用容器命令

容器生命周期管理命令:

命令 作用 示例
docker run 创建并启动一个新容器 docker run -d -p 8080:80 nginx
docker ps 查看正在运行的容器 docker ps
docker start 启动已停止的容器 docker start mycontainer
docker stop 停止正在运行的容器 docker stop mycontainer
docker restart 重启容器 docker restart mycontainer
docker rm 删除容器(只能删除已停止的) docker rm mycontainer
docker kill 强制终止容器 docker kill mycontainer

容器状态与交互命令:

命令 作用 示例
docker logs 查看容器输出日志 docker logs mycontainer
docker exec 在运行容器中执行命令(推荐) docker exec -it mycontainer bash
docker top 查看容器内进程列表 docker top mycontainer
docker inspect 查看容器详细信息(JSON) docker inspect mycontainer
docker stats 实时查看容器资源占用 docker stats

容器创建与运行常用参数:

选项 含义 示例
-d 后台运行容器 docker run -d nginx
--name 给容器命名 --name mynginx
-p 映射端口 -p 8080:80
-v 挂载数据卷 -v /host/path:/container/path
-e 设置环境变量 -e MYSQL_ROOT_PASSWORD=123456
--rm 容器退出后自动删除 --rm
--restart 设置重启策略 --restart=always

五. 多容器编排 (Docker Compose)

5.1 Docker Compose是什么

Docker Compose 是一个用来定义和运行多容器 Docker 应用的工具。通过一个名为 docker-compose.yml 的文件,描述服务(service)、网络、卷等所有内容。

5.2 基本语法

docker-compose文件中可以定义多个相互关联的应用容器,每一个应用容器被称为一个服务(service)。由于service就是在定义某个应用的运行时参数,因此与docker run参数非常相似。

举例来说,用docker run部署MySQL的命令如下:

 docker run -d \
   --name mysql \
   -p 3306:3306 \
   -e TZ=Asia/Shanghai \
   -e MYSQL_ROOT_PASSWORD=123 \
   -v ./mysql/data:/var/lib/mysql \
   -v ./mysql/conf:/etc/mysql/conf.d \
   -v ./mysql/init:/docker-entrypoint-initdb.d \
   --network hmall
   mysql

如果用docker-compose.yml文件来定义,就是这样:

 version: "3.8"
 ​
 services:
   mysql:
     image: mysql
     container_name: mysql
     ports:
       - "3306:3306"
     environment:
       TZ: Asia/Shanghai
       MYSQL_ROOT_PASSWORD: 123
     volumes:
       - "./mysql/conf:/etc/mysql/conf.d"
       - "./mysql/data:/var/lib/mysql"
     networks:
       - new
 networks:
   new:
     name: hmall

5.3 常用命令

命令 说明
docker-compose up 启动所有服务(需在文件目录下)
docker-compose up -d 后台启动所有服务
docker-compose down 停止并删除容器、网络、卷
docker-compose ps 查看服务状态
docker-compose logs 查看所有容器日志
docker-compose build 构建镜像(如果用了 build:
docker-compose restart 重启所有服务

官方文档: Docker Compose命令

六. 数据卷(Volume)

6.1 数据卷是什么

数据卷(volume)是一个虚拟目录,是容器内目录宿主机目录之间映射的桥梁。数据卷常用于持久化和共享数据。通过数据卷,实现了容器内目录与宿主机目录之间的双向绑定

注意:容器与数据卷的挂载要在创建容器时配置,对于创建好的容器,是不能设置数据卷的。而且创建容器的过程中,数据卷会自动创建

6.2 数据卷常用命令

命令 作用 示例
docker volume create 创建一个数据卷 docker volume create mydata
docker volume ls 查看所有数据卷 docker volume ls
docker volume inspect 查看数据卷详细信息(如挂载路径) docker volume inspect mydata
docker volume rm 删除一个数据卷(不能被容器使用中) docker volume rm mydata

注意: 一般我们在启动容器时挂载数据卷,常和docker run命令搭配使用:

 # 启动容器并挂载
 docker run -d -v mydata:/var/lib/mysql --name mysql-test mysql:8.0

6.3 命名卷与绑定挂载

特性 命名卷(Named Volume) 绑定挂载(Bind Mount)
数据存储位置 由 Docker 管理(/var/lib/docker/volumes/ 宿主机的任意路径(如 ./init.sql
跨平台兼容性 好(Docker 自动处理路径格式) 差(需手动适配 Windows/macOS/Linux 路径)
数据持久化 容器删除后数据保留 容器删除后不影响宿主机文件
使用场景 应用数据持久化(如数据库、缓存) 配置文件注入、临时数据交换

如对于专业练习exercise1中的docker-compose.yml文件可这样编写(既使用了命名卷又使用了绑定挂载):

 version: '3.8'
 ​
 services:
   mysql:
     # 使用官方 MySQL 镜像
     image: mysql:8.0
     # 设置容器名称
     container_name: exercise1
     # 配置环境变量
     environment:
       # 设置 root 用户密码
       MYSQL_ROOT_PASSWORD: 123456
     # 配置数据卷持久化
     volumes:
       # 使用 named volume 持久化 MySQL 数据目录
       - mysql-data:/var/lib/mysql
       # 使用绑定挂载,将本地的 init.sql 绑定到容器内指定目录。MySQL 镜像启动时,会自动执行 /docker-entrypoint-initdb.d/ 目录下的 SQL 文件,用于初始化数据库。
       - ./init.sql:/docker-entrypoint-initdb.d/init.sql
     # 暴露端口到主机
     ports:
       - "3306:3306"
     # 设置容器重启策略
     restart: always
 ​
 # 定义 named volume
 volumes:
   mysql-data:

七. 网络(Network)

7.1 Docker网络的作用

Docker 提供了强大且灵活的网络功能,用于容器之间的通信、容器与主机通信,以及跨主机通信

注意: 容器的网络IP其实是一个虚拟的IP,其值并不固定与某一个容器绑定,如果我们在开发时写死某个IP,而在部署时很可能MySQL容器的IP会发生变化,连接会失败。

官方文档: Docker网络

7.2 Docker中的网络类型

网络模式 作用说明
bridge(桥接) 默认网络模式,适合单主机上多个容器通信
host(主机) 容器与宿主机共用网络栈,无隔离,适合性能要求高的场景
none(无网络) 容器完全没有网络接口,隔离性最强
container:<name> 容器共享另一个容器的网络,适合多个进程需要共享网络时
自定义 bridge 网络 推荐方式,支持容器名称互通 + DNS 解析

7.3 网络常用命令

命令 作用 示例
docker network ls 查看所有 Docker 网络 docker network ls
docker network inspect 查看某个网络的详细信息 docker network inspect mynet
docker network create 创建一个自定义网络 docker network create mynet
docker network rm 删除一个自定义网络 docker network rm mynet
docker network connect 将容器连接到某个网络 docker network connect mynet mycontainer
docker network disconnect 将容器从网络中断开 docker network disconnect mynet mycontainer
docker run --network 创建容器时指定加入某网络 docker run --network=mynet nginx

对于专业练习exercise2中的docker-compose.yml文件自定义桥接网络可这样编写:

 version: '3.8'
 ​
 # 自定义 bridge 网络
 networks:
   mynet:
     driver: bridge  # 使用 bridge 驱动,实现容器间隔离通信
 ​
 services:
   # Web 服务
   web:
     build: .  # 从当前目录的 Dockerfile 构建镜像
     ports:
       - "5000:5000"  # 主机端口映射到容器端口,外部可访问
     networks:
       - mynet  # 加入自定义 bridge 网络
     depends_on:
       - redis  # 依赖 redis 服务,确保启动顺序
     
 ​
   # Redis 服务
   redis:
     image: redis:7.2-alpine  # 轻量 Redis 镜像
     networks:
       - mynet  # 加入自定义 bridge 网络
     volumes:
       - redis-data:/data  # 持久化 Redis 数据
 ​
 # 持久化 Volume
 volumes:
   redis-data:

八. RAG 智能问答系统容器化实践

项目待发布...

Logo

加入社区!打开量化的大门,首批课程上线啦!

更多推荐