Docker学习与使用

文章目录

Docker 简介

Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖打包到一个轻量级、可移植的容器 中,然后在任何运行 Docker 的环境中一致地运行。

如果说虚拟机是"装修好的整间新房 "(需要独立地基、水电),那么 Docker 就是"宜家的模块化储物箱"(即拿即用、可叠放、搬家直接抱走)。

核心概念

概念 通俗解释 核心特点 类比
镜像(Image) 容器的「模板」,包含运行应用所需的代码、依赖、配置(如 nginx 镜像) 只读、分层存储、可复用 面向对象中的「类」
容器(Container) 镜像的「运行实例」,是独立的运行环境(启动镜像即创建容器) 可读写、独立隔离、生命周期可控 面向对象中的「对象」
数据卷(Volume) 用于容器数据持久化的目录,独立于容器生命周期 持久化、可共享、跨容器使用 容器的「外部硬盘」
仓库(Registry) 存储镜像的仓库(如 Docker Hub 公有仓库,Harbor 私有仓库) 拉取/推送镜像、私有/公有部署 镜像的「GitHub」
Dockerfile 构建自定义镜像的「脚本文件」,定义镜像的构建步骤 代码化构建、可版本控制、可复用 镜像的「配方」
Docker Compose 定义和运行多容器应用的「编排文件」(YAML 格式) 一键启停、依赖管理、环境隔离 应用的「说明书」
网络(Network) 容器间通信的「虚拟通道」,实现容器隔离与互联 隔离、可自定义、支持多驱动 容器的「路由器」

主要优势

环境一致 :解决"在我机器上能跑"的问题,开发、测试、生产环境无差异。
轻量高效 :共享宿主机操作系统内核,比传统虚拟机启动快(秒级),占用资源小。
可移植性 :一次打包,可在任何支持 Docker 的系统(Linux、Windows、macOS)运行。
简化配置 :通过 Dockerfiledocker-compose.yml 轻松管理应用依赖和服务编排。
隔离性:每个容器拥有独立的文件系统、网络和进程空间,互不干扰。

Docker vs 传统虚拟机

特性 Docker 容器 传统虚拟机
启动速度 秒级 分钟级
磁盘占用 MB 级 GB 级
性能损耗 几乎为零 较高
隔离级别 进程级隔离 完全系统隔离
内核共享 共享宿主机内核 每个 VM 独立内核

常见使用场景

场景 说明 典型例子
开发环境统一 让团队所有成员的开发环境完全一致,避免"在我电脑上能跑"的问题 前端:Node.js + Redis + MySQL 一键启动
微服务架构 每个服务独立打包成镜像,独立部署、升级、伸缩 订单服务、用户服务、支付服务各跑一个容器
CI/CD 流水线 在自动化构建、测试、部署流程中使用容器隔离环境 Git push 触发构建镜像 → 推送到仓库 → 自动部署
应用打包分发 将应用及其所有依赖打包成一个镜像,随处运行 内部工具打包分发,客户直接 docker run
快速搭建中间件 无需安装配置,一行命令启动数据库、缓存等 docker run -d redis、docker run -d mysql
本地测试/实验 临时运行某个环境,用完即删,不影响宿主机 测试不同版本 Python、尝试新软件

Windows 上安装 Docker

最官方和推荐的方法是安装 Docker Desktop。它会提供一个完整的图形化管理界面,并在后台帮你配置好运行环境。整个过程主要分为以下三步:

第一步:检查 Windows 系统

  • 操作系统:
    Windows 11/10 :需要 22H2 或更高版本
    💡 如何检查系统信息?
    可以按 Win + R 键,输入 winver 并回车,在弹出的窗口中就能看到详细的系统版本和内部版本号。
  • 硬件要求:
    • 64位处理器,且必须支持并已在 BIOS/UEFI 设置中开启硬件虚拟化(即 Intel VT-x 或 AMD-V,验证方法:打开任务管理器→"性能"选项卡→查看"虚拟化"是否显示"已启用")。
    • 系统内存至少 4 GB(强烈建议 8 GB 以上)。

第二步:安装并配置WSL 2后端

  1. 启用 WSL 2 功能 :以管理员身份打开 PowerShell 或命令提示符,输入以下命令并回车
bash 复制代码
wsl --install

这个命令会自动完成安装 WSL 所需的一切(包括Linux内核和设置为WSL 2)。安装完成后,根据提示重启电脑。

  1. 更新 WSL 内核:打开命令行,运行以下命令确保WSL是最新版本:
bash 复制代码
wsl --update

第三步:下载并安装 Docker Desktop

  1. 下载安装程序:前往 Docker 官方下载页面,下载 Docker Desktop for Windows 的稳定版安装程序。Intel Core i3/i5/i7/i9、AMD Ryzen 系列选 AMD64 版本。

    Docker 官方虽未在首页提供历史版本的下载入口,但其发布页面和文档中仍保留了部分历史信息。访问 Docker Desktop 官方发布说明页面:Docker 官方维护了Windows 的 Release Notes 页面,其中包含了每个版本的发布说明和对应的下载链接。

  2. 运行安装程序:

    找到下载的 Docker Desktop Installer.exe,双击运行,点击 "OK",等待安装完成。

  3. 完成安装并验证:

    • 安装完成后,点击 "Close" 并重启电脑(如果被提示的话)。
    • 重启后,从开始菜单启动 Docker Desktop
    • 程序启动后,你可以在任务栏通知区域看到一个鲸鱼图标的 Docker 标志。
    • 打开命令行(PowerShell 或 CMD),输入以下命令验证是否安装成功:
    bash 复制代码
    docker --version
    docker run hello-world

docker run hello-world出现错误 A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.这是由于网络原因,直接从 Docker Hub 拉取镜像可能会非常慢或失败,需要配置国内镜像加速器,配置步骤:

  1. 打开 Docker Desktop,点击右上角的 Settings(⚙️图标)

  2. 选择左侧菜单的 Docker Engine

  3. 在配置文件中添加 registry-mirrors 项:

    json 复制代码
    "registry-mirrors": [
        "https://docker.1ms.run",
        "https://docker.xuanyuan.me"
      ]

    上面是毫秒镜像和轩辕镜像的镜像源,免费且无需注册。

  4. 点击右下角的 Apply & Restart 按钮

  5. 再次运行 docker run hello-world 测试,看到镜像被正常拉取并打印出 Hello from Docker! 的欢迎信息,说明配置成功了。

Docker使用

一、镜像管理

命令 作用 示例 注意事项
docker pull 镜像名:标签 拉取镜像(默认从 Docker Hub) docker pull nginx:1.24 标签省略默认拉取 latest(不稳定),建议指定版本
docker images 查看本地所有镜像 docker images 加 -q 只显示镜像 ID:docker images -q
docker rmi 镜像ID/镜像名 删除镜像(需先删依赖容器) docker rmi nginx:latest 强制删除:docker rmi -f 镜像ID(如果有容器在使用。谨慎,避免删错)
docker save -o 文件名.tar 镜像 导出镜像为压缩包 docker save -o nginx.tar nginx 可批量导出:docker save -o apps.tar nginx:latest hello-world:latest
docker load -i 文件名.tar 导入本地镜像包 docker load -i nginx.tar 导入后自动保留原标签,无需重新打标签
docker search 镜像名 搜索 Docker Hub 镜像 docker search nginx 加 --filter=stars=1000 筛选高星镜像:docker search --filter=stars=1000 nginx
docker tag 原镜像 新镜像:标签 给镜像打新标签(用于推送私有仓库) docker tag hello-world:latest localhost:5000/my-hello:test 推送前必须打仓库地址标签
docker push 镜像名:标签 推送镜像到仓库 docker push localhost:5000/my-hello:test

二、容器管理

命令 作用 示例 扩展说明
docker run [参数] 镜像 创建并启动容器 docker run -d -p 80:80 --name nginx nginx 核心参数见下表
docker ps 查看运行中的容器 docker ps 加 -a 查看所有容器(含停止的);加 -q 只显示 ID
docker start/stop/restart 容器ID/名 启动 / 停止 / 重启容器 docker restart nginx 批量操作:docker start $(docker ps -aq)(启动所有容器,注意 在Linux/macOS 的 Bash 终端支持,但是Windows 中的PowerShell和CMD不支持)
docker rm 容器ID/名 删除容器(需先停止) docker rm nginx 强制删除运行中容器:docker rm -f nginx
docker exec -it 容器ID/名 命令 进入容器执行命令(交互模式) docker exec -it nginx /bin/bash 非交互执行:docker exec nginx ls /usr/share/nginx/html
docker logs -f 容器ID/名 实时查看容器日志 docker logs -f nginx 加 --tail=100 只看最后 100 行:docker logs --tail=100 -f nginx
docker inspect 容器ID/名 查看容器详细信息(IP、挂载等) docker inspect nginx 过滤查看 IP:docker inspect -f '{{.NetworkSettings.IPAddress}}' nginx
docker rename 旧名 新名 容器重命名 docker rename nginx nginx-proxy 重命名不影响容器运行
docker cp 主机路径 容器ID:容器路径 主机→容器拷贝文件 docker cp index.html nginx:/usr/share/nginx/html 反向拷贝(容器→主机):docker cp nginx:/usr/share/nginx/html/index.html ./
docker export 容器ID -o 文件名.tar 导出容器为镜像包(仅含文件系统) docker export nginx -o nginx-container.tar 与 save 区别:save 存镜像(分层),export 存容器(扁平)
docker import 文件名.tar 新镜像:标签 导入容器包为镜像 docker import nginx-container.tar my-nginx:1.0 导入后需重新指定启动命令-g "daemon off;"

docker run 核心参数(细化说明)

参数 作用 示例 实用场景
-d 后台运行容器(守护进程模式) -d 生产环境必加,避免终端关闭容器停止
-p 端口映射(主机:容器) -p 8080:8080 多个端口映射:-p 80:80 -p 443:443
-P 随机映射容器暴露的所有端口 -P 测试场景,无需手动指定端口
--name 指定容器名称(唯一) --name my_web 便于管理,避免默认随机名称
-e 设置环境变量 -e MYSQL_ROOT_PASSWORD=123456 多个变量:-e KEY1=VAL1 -e KEY2=VAL2
-v 挂载数据卷 / 目录 -v nginx-vol:/usr/share/nginx/html 权限控制::ro 只读,:rw 读写(默认)
--network 指定容器网络 --network my-net 自定义网络实现容器名互通
--restart 容器重启策略 --restart always 可选值:always(始终重启)、on-failure(失败时重启)、no(不重启)
--memory 限制容器内存 --memory 1G 防止容器占用过多主机资源
--cpus 限制容器 CPU 核心数 --cpus 2 限制使用 2 个核心,小数也可:--cpus 1.5
--privileged 赋予容器主机特权(慎用) --privileged 需访问主机硬件 / 内核时使用
  • 示例:运行一个 Web 服务器
bash 复制代码
# 1. 后台运行 Nginx,将 80 端口映射到主机的 8080
docker run -d --name my-nginx -p 8080:80 nginx

# 2. 验证:打开浏览器访问 http://localhost:8080,应该能看到 Nginx 欢迎页

# 3. 查看日志
docker logs my-nginx

# 4. 进入容器内部修改默认页面
docker exec -it my-nginx bash
# 进入后执行:
echo "<h1>Hello from Docker</h1>" > /usr/share/nginx/html/index.html
exit

# 5. 刷新浏览器,会看到修改后的内容

# 6. 停止并删除容器
docker stop my-nginx
docker rm my-nginx

三、Dockerfile(构建自己的镜像)

Dockerfile 就是一个文本文件,其中包含一个个的指令(Instruction),用指令来说明要执行什么操作来构建镜像。每一个指令都会形成一层Layer。

指令 作用 示例 注意事项
FROM 指定基础镜像(必选,第一行) FROM python:3.9-slim 优先选轻量镜像(alpine < 10MB),减少体积
RUN 构建时执行命令(分层构建) RUN pip install 多命令合并用 &&,减少分层:RUN yum update && yum install -y nginx && yum clean all
COPY 复制主机文件到容器(本地→容器) COPY app.py . 支持通配符:COPY *.jar /app/;路径必须是构建上下文内的文件
ADD 复制文件(支持解压、URL) ADD app.tar.gz /usr/local/ 慎用 URL 下载(增加镜像体积),建议用 RUN wget
WORKDIR 设置工作目录(后续指令的默认目录) WORKDIR /app 自动创建不存在的目录,推荐用绝对路径
ENV 设置环境变量(构建 / 运行时均生效) ENV JAVA_HOME /usr/local/jdk8 引用变量:ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 声明容器端口(仅说明,无映射) EXPOSE 8080 仅为文档说明,运行时仍需 -p 映射
CMD 容器启动时执行命令(可被覆盖) CMD ["nginx", "-g", "daemon off;"] 仅最后一个 CMD 生效;运行时可覆盖:docker run 镜像 自定义命令
ENTRYPOINT 容器启动时执行命令(不可被覆盖) ENTRYPOINT ["java", "-jar"] 结合 CMD 传参:ENTRYPOINT ["java", "-jar"] + CMD ["app.jar"]
VOLUME 声明数据卷(建议运行时再挂载) VOLUME ["/data"] 运行时可通过 -v 覆盖:docker run -v 卷名:/data 镜像
USER 指定容器运行用户 USER nginx 需先在镜像中创建用户:RUN useradd -m nginx
  • 示例:构建一个简单的 Python Web 应用

    1. 创建项目文件夹:

      bash 复制代码
      mkdir my-python-app
      cd my-python-app
    2. 创建 app.py

      python 复制代码
      from flask import Flask
      app = Flask(__name__)
      
      @app.route('/')
      def hello():
          return 'Hello from Docker!'
      
      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=5001)
    3. 创建 Dockerfile

      text 复制代码
      # 使用 Python 3.9 作为基础镜像
      FROM python:3.9-slim
      
      # 设置工作目录
      WORKDIR /app
      
      # 复制依赖文件
      COPY requirements.txt .
      
      # 安装依赖
      RUN pip install --no-cache-dir -r requirements.txt
      
      # 复制应用代码
      COPY app.py .
      
      # 暴露端口
      EXPOSE 5001
      
      # 启动命令
      CMD ["python", "app.py"]
    4. 创建 requirements.txt

      text 复制代码
      flask
    5. 构建并运行:

      bash 复制代码
      # 构建镜像(注意最后的 . 表示当前目录)
      docker build -t my-python-app .
      
      # 运行容器
      docker run -d -p 8000:5001 --name my-app my-python-app
      
      # 访问 http://localhost:8000 查看效果
  • 示例:Docker中运行jar包:

    1. 准备工作
      创建一个专门的目录(例如my-docker-app),并将 JAR 包放入其中。

      text 复制代码
      /my-docker-app
      ├── Dockerfile    # 没有后缀名
      └── user-service-1.0.0.jar
    2. 编写 Dockerfile:

      text 复制代码
      # 第一阶段:使用官方的 OpenJDK 运行时作为一个轻量级的父镜像
      # 推荐使用 eclipse-temurin(原 AdoptOpenJDK)或官方的 openjdk 镜像
      FROM eclipse-temurin:11-jre-alpine
      
      # 在镜像中创建一个目录来存放我们的应用程序
      WORKDIR /app
      
      # 将宿主机的 JAR 文件复制到镜像中的工作目录下,并重命名为 app.jar
      # 第一个参数是宿主机文件,第二个参数是镜像内路径
      COPY user-service-0.0.1-SNAPSHOT.jar app.jar
      
      # 声明容器运行时暴露的端口号,这个数字必须和你的 Spring Boot 应用配置的服务器端口一致
      EXPOSE 8081
      
      # 指定容器启动时运行的命令,使用 java -jar 命令来启动我们的应用程序
      ENTRYPOINT ["java", "-jar", "app.jar"]
      
      # 可以添加额外的 JVM 参数,例如设置内存或启用调试
      # ENTRYPOINT ["java", "-Xmx256m", "-jar", "app.jar"]
    3. 构建 Docker 镜像
      在包含 Dockerfile 和 jar 包的目录下,打开终端(命令行),执行以下命令:

      bash 复制代码
      docker build -t user-service-app:1.0.0 .

      -t user-service-app:1.0.0:为镜像指定一个名称和标签(tag),格式为 名称:标签
      .:表示当前目录是构建上下文(Context),Docker 会查找当前目录下的 Dockerfile。

    4. 运行 Docker 容器
      镜像构建成功后,就可以通过镜像来创建并运行容器了:

      bash 复制代码
      docker run -d -p 8081:8081 --name my-running-app user-service-app:1.0.0

      通过访问 http://localhost:8081 查看效果。

四、Docker Compose(多容器编排)

当需要多个服务配合时(如 Web + Redis + MySQL),使用 docker-compose.yml。

命令 作用 示例 扩展说明
docker-compose up 创建并启动所有容器(前台) docker-compose up 加 -d 后台运行:docker-compose up -d
docker-compose up -d --build 构建镜像并启动容器 docker-compose up -d --build 镜像有更新时强制重新构建
docker-compose down 停止并删除容器、网络(保留数据卷) docker-compose down 加 -v 删除数据卷:docker-compose down -v(谨慎)
docker-compose ps 查看 Compose 管理的容器 docker-compose ps 加 -a 查看所有(含停止的)
docker-compose logs 查看容器日志 docker-compose logs nginx 加 -f 实时查看:docker-compose logs -f tomcat
docker-compose restart 重启指定 / 所有容器 docker-compose restart mysql 重启所有:docker-compose restart
docker-compose stop/start 停止 / 启动容器 docker-compose stop 仅停止容器,不删除
docker-compose exec 进入指定容器 docker-compose exec nginx bash 等同于 docker exec,无需记容器名
docker-compose build 构建指定 / 所有镜像 docker-compose build tomcat 加 --no-cache 无缓存构建:docker-compose build --no-cache
  • 示例:搭建一个访客计数器系统,包含三个服务:

    • 前端 Web:显示访问次数,每次刷新页面数字 +1
    • 后端 API:处理计数逻辑,提供 REST API
    • Redis:存储计数值(内存数据库)

    完整项目结构,创建一个新目录,比如 demo-compose,然后创建以下文件:

    text 复制代码
    demo-compose\          (项目根目录)
    ├── docker-compose.yml
    ├── web\
    │   ├── index.html
    │   └── nginx.conf       
    └── api\
        ├── Dockerfile
        ├── requirements.txt
        └── app.py
    1. 创建前端页面 (web/index.html)

      html 复制代码
      <!DOCTYPE html>
      <html>
      <head>
          <meta charset="UTF-8"> 
          <title>Docker Compose 演示 - 访客计数器</title>
          <style>
              body { font-family: Arial; text-align: center; margin-top: 50px; }
              .count { font-size: 48px; font-weight: bold; color: #2c3e50; }
              button { padding: 10px 20px; font-size: 16px; cursor: pointer; }
              .log { margin-top: 30px; font-size: 12px; color: #7f8c8d; }
          </style>
      </head>
      <body>
          <h1>🐳 Docker Compose 演示</h1>
          <p>每次刷新页面,计数器 +1</p>
          <div class="count" id="count">加载中...</div>
          <button onclick="refresh()">🔄 手动刷新</button>
          <div class="log" id="log"></div>
      
          <script>
              function refresh() {
                  fetch('/api/count')
                      .then(res => res.json())
                      .then(data => {
                          document.getElementById('count').innerHTML = data.count;
                          document.getElementById('log').innerHTML = 
                              `最后更新: ${new Date().toLocaleTimeString()} | 数据来自 Redis`;
                      })
                      .catch(err => {
                          document.getElementById('count').innerHTML = '连接失败';
                      });
              }
              refresh();
              setInterval(refresh, 2000);
          </script>
      </body>
      </html>
    2. 创建后端 API (api/app.py)

      python 复制代码
      from flask import Flask, jsonify
      from flask_cors import CORS
      import redis
      import os
      
      app = Flask(__name__)
      CORS(app)
      
      # 连接到 Redis(通过服务名 "redis")
      r = redis.Redis(host='redis', port=6379, decode_responses=True)
      
      @app.route('/api/count')
      def get_count():
          # 计数器 +1
          count = r.incr('visitor_count')
          print(f"✅ 收到请求,当前计数: {count}")  # 这行会显示在 docker logs 中
          return jsonify({'count': count})
      
      if __name__ == '__main__':
          app.run(host='0.0.0.0', port=5005)
    3. 创建 requirements.txt (api/requirements.txt)

      text 复制代码
      flask
      redis
      flask-cors
    4. 创建 docker-compose.yml

      yaml 复制代码
      version: '3.8'
      
      services:
        # Redis 服务(存储数据)
        redis:
          image: redis:alpine
          container_name: demo-redis
          restart: always
          ports:
            - "6379:6379"      # 可选,方便外部查看
          networks:
            - demo-network
      
        # API 服务(后端逻辑)
        api:
          build: ./api
          container_name: demo-api
          restart: always
          ports:
            - "5005:5005"
          depends_on:
            - redis
          networks:
            - demo-network
          # 显式声明启动命令,确保能看到打印日志
          command: python app.py
      
        # Web 服务(前端界面)
        web:
          image: nginx:alpine
          container_name: demo-web
          restart: always
          ports:
            - "8080:80"
          volumes:
            - ./web:/usr/share/nginx/html:ro   # 静态文件挂载
            - ./web/nginx.conf:/etc/nginx/conf.d/default.conf:ro   # 配置文件挂载
          depends_on:
            - api
          networks:
            - demo-network
            
      networks:
        demo-network:
          driver: bridge

      volumes 挂载语法基本格式:

      yaml 复制代码
      	volumes:
      	  - "宿主机路径:容器内路径:可选参数"
    5. 创建 API 的 Dockerfile (api/Dockerfile)

      text 复制代码
      FROM python:3.9-slim
      
      WORKDIR /app
      
      COPY requirements.txt .
      RUN pip install --no-cache-dir -r requirements.txt
      
      COPY app.py .
      
      # 确保 Python 输出不缓冲,这样日志能实时显示
      ENV PYTHONUNBUFFERED=1
      
      CMD ["python", "app.py"]
    6. 创建 Nginx 配置文件 web/nginx.conf

      nginx 复制代码
      server {
          listen 80;
          server_name localhost;
          
          # 静态文件(前端页面)
          location / {
              root /usr/share/nginx/html;
              index index.html;
              try_files $uri $uri/ /index.html;
          }
          
          # API 请求转发到后端服务
          location /api/ {
              proxy_pass http://api:5005;
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          }
      }
    7. 运行体验

      bash 复制代码
      # 1. 启动所有服务(-d 后台运行)
      docker compose up -d
      
      # 2. 查看实时日志(关键!能清楚看到服务间通信)
      docker compose logs -f

      执行后会看到如下日志:

      打开浏览器 :访问 http://localhost:8080

      每刷新一次页面(或等待2秒自动刷新),网页上会看到:

      • 网页上的数字 +1
      • 终端日志中同时出现 ✅ 收到请求,当前计数: X

    该案例中包含了如下特性:

    特性 通过这个案例如何直观感受
    服务发现 API 代码中用 host='redis' 连接,而不是 IP 地址
    依赖管理 depends_on 确保 Redis 先于 API 启动
    网络隔离 三个服务在同一个 demo-network 中互通
    一键启动 一个命令启动 3 个服务,无需手动 docker run 3 次
    日志聚合 docker compose logs -f 看到所有服务的输出混在一起
    声明式配置 整个系统架构写在 YAML 文件中,可版本控制

五、数据管理

Docker Volume 是一种用于在容器之间共享和持久化数据的存储机制。与绑定挂载 不同,Docker Volume 是完全由 Docker 管理的,独立于宿主机的文件系统 ,提供了更高的灵活性和安全性。Volume 可以存储在宿主机的文件系统中,也可以通过网络文件系统(如 NFS)或云存储服务进行远程存储。使用 Docker Volume,容器可以在不同的生命周期中共享数据,这在需要持久化存储(如数据库数据、日志文件等)或在多个容器之间共享文件时特别有用。Docker 提供了多种与 Volume 相关的命令,允许用户创建、管理和删除卷。此外,Volume 的隔离特性确保了宿主机和容器之间的安全性,减少了对宿主机文件系统的依赖,从而提高了应用的可移植性和数据的可靠性。

命令 作用 示例 扩展说明
docker volume create 创建数据卷 docker volume create my-data 可指定驱动和选项
docker volume ls 列出所有数据卷 docker volume ls 加 -q 只显示ID,加 -f 过滤
docker volume inspect 查看数据卷详情 docker volume inspect my-data 显示挂载点、驱动等信息
docker volume rm 删除数据卷 docker volume rm my-data 只能删除未被使用的卷
docker volume prune 删除所有未使用的卷 docker volume prune 加 -f 跳过确认,加-a 删除所有未挂载的卷

挂载类型对比

类型 管理方式 位置 适用场景 示例
数据卷(Volume) Docker 管理 C:\ProgramData\Docker\volumes\(Win) 生产环境、数据持久化 -v my-data:/app/data
绑定挂载(Bind Mount) 用户管理 宿主机任意路径 开发环境、配置文件注入 -v ./local:/app/config(当前目录(./)下的 local 文件夹映射到容器内的/app/config目录中)
临时挂载(tmpfs) 内存 内存 临时缓存、敏感数据 --tmpfs /app/tmp
  • 案例:Redis 数据持久化

    启动一个 Redis 容器,写入数据后删除容器,重新创建后数据依然存在。项目结构:

    text 复制代码
    redis-demo/
    └── docker-compose.yml
    1. 创建 docker-compose.yml

      yaml 复制代码
      version: '3.8'
      
      services:
        redis:
          image: redis:alpine
          container_name: my-redis
          restart: always
          ports:
            - "6379:6379"
          volumes:
            - ./data:/data    # 关键:数据持久化
    2. 启动并测试

      bash 复制代码
      # 启动容器
      docker compose up -d
      
      # 进入 Redis 写入数据
      docker exec -it my-redis redis-cli
      # 在 Redis 命令行中执行:
      SET mykey "Hello Docker"
      GET mykey
      EXIT
      
      # 删除容器(模拟故障或升级)
      docker compose down
      
      # 重新创建容器
      docker compose up -d
      
      # 再次进入 Redis,数据还在!
      docker exec -it my-redis redis-cli
      GET mykey   # 应该返回 "Hello Docker"

六、搭建私有仓库

在 Docker 中创建一个本地的私有仓库

  • 第一步:快速启动一个本地仓库
    在命令行窗口中执行以下命令,它会下载并运行一个私有仓库容器:
bash 复制代码
docker run -d  --name my-registry  -p 5000:5000  --restart=always  registry:2

命令参数详解
-d:在后台运行容器。
--name my-registry:给容器命名为 my-registry,方便管理。
-p 5000:5000:将宿主机的 5000 端口映射到容器的 5000 端口。这样你就可以通过 localhost:5000 访问仓库了。
--restart=always:设置容器在 Docker 重启后自动启动,比较方便。
registry:2:使用官方 Registry 服务的第 2 版镜像。

关于数据持久化

上面的命令没有挂载数据卷。这意味着,如果你删除这个 my-registry 容器,里面存储的所有镜像也会随之丢失。

如果希望保存镜像数据,可以在 docker run 命令中添加 -v /your/data/path:/var/lib/registry 参数,将容器内的镜像存储目录映射到电脑的硬盘上。例如:docker run -d --name my-registry -p 5000:5000 --restart=always -v D:/demo/docker/v:/var/lib/registry registry:2

验证仓库是否启动成功:

执行以下命令,如果返回 {},说明仓库已经成功运行。

bash 复制代码
curl http://localhost:5000/v2/_catalog
  • 第二步:配置 Docker 允许 HTTP 访问
    Docker 出于安全考虑,默认只允许通过 HTTPS 访问仓库。但我们自己搭建的本地测试仓库用的是 HTTP,所以需要手动将其设置为"可信的"仓库(insecure-registries)。

    1. 打开 Docker Desktop,点击顶部导航栏的 设置 (Settings) 图标(⚙️)。
    2. 从左侧菜单中选择 Docker Engine。
    3. 在 JSON 配置中,添加或修改 insecure-registries 字段:
    json 复制代码
    {
      "builder": {
        "gc": {
          "defaultKeepStorage": "20GB",
          "enabled": true
        }
      },
      "experimental": false,
      "insecure-registries": [
        "localhost:5000"
      ],
      "registry-mirrors": [
        "https://docker.1ms.run",
        "https://docker.xuanyuan.me"
      ]
    }
    1. 点击界面右下角的 Apply & Restart 按钮,Docker 会自动重启以使配置生效。

七、释放空间

Docker 使用了"写时复制"(Copy-on-Write)机制和分层存储,删除镜像并不会立即释放磁盘空间给主机系统,这些空间会被 Docker 保留以供后续使用。

  • 释放磁盘空间:
    • 方法一:通过 Docker Desktop GUI 清理

      1. 打开 Docker Desktop
      2. 找到Troubleshoot(故障排除),点击 Clean / Purge data
    • 方法二:使用命令行清理

      bash 复制代码
      # 删除所有停止的容器、未使用的网络、悬挂镜像和构建缓存
      docker system prune
      
      # 单独删除悬挂镜像(none标签的)
      docker image prune
      
      # 删除所有未被任何容器引用的镜像
      docker image prune -a
      
      # 更加彻底的清理(包括未使用的镜像和卷,需要确认)
      docker system prune -a --volumes

总结

Docker 通过容器化技术,让应用交付变得更简单、可靠、高效,已成为现代云原生开发和 DevOps 实践的基石工具。

相关推荐
%KT%11 小时前
Windows安装wsl2和docker desktop,部署qdrant向量数据库
运维·docker·容器
星夜夏空9911 小时前
STM32单片机学习(22) —— I2C通信协议
stm32·单片机·学习
香蕉鼠片11 小时前
CNN学习时的代码
人工智能·学习·cnn
PythonAI实战君11 小时前
Docker Compose 部署 MySQL 中文乱码避坑指南
docker·容器
searchforAI11 小时前
5款AI笔记工具实测:导入体验、结构化输出、后续能力逐项对比
人工智能·笔记·学习·ai·chatgpt·aigc·音视频
pixcarp11 小时前
Redis ZSet:底层设计与实践
数据库·redis·后端·学习·golang·web
PythonAI实战君11 小时前
若依后台管理系统 - Docker Compose 阿里云部署指南
后端·docker
小匠石钧知11 小时前
01_以RockyLinux的镜像为基础_构建自己开发学习所需的镜像
linux·docker·jdk·mariadb
学习中.........11 小时前
Agent 记忆力机制设计学习路线:从主流项目中学习
学习