当前位置: 首页 > ops >正文

Docker入门到精通:从零基础到生产部署

前言:为什么你需要学习Docker?

想象一下,你开发了一个应用程序,在你的电脑上运行完美,但当你把它交给同事或部署到服务器时,却出现了各种奇怪的问题。这就是著名的"在我机器上能运行"问题。

Docker就是解决这个问题的神器!它能确保你的应用在任何地方都能一致地运行,无论是在你的笔记本电脑、数据中心的服务器,还是在云平台上。

学习路径图

安装Docker
基础操作
Dockerfile
Docker Compose
网络与存储
实战项目
生产部署

本手册专为零基础小白设计,通过简单易懂的语言、实用示例和互动练习,带你从Docker小白成长为能够熟练使用Docker的开发者。


第一章:Docker基础概念

1.1 什么是Docker?

Docker是一种容器化技术,它允许你将应用程序及其所有依赖(代码、库、环境变量等)打包到一个轻量级、可移植的"容器"中。

类比理解

┌──────────────────────────────────────┐
│           宿主机操作系统             │
├───────────┬───────────┬──────────────┤
│ 容器1     │ 容器2     │ 容器3        │
│ (应用A)   │ (应用B)   │ (应用C)      │
│  ┌─────┐  │  ┌─────┐  │  ┌─────┐     │
│  │应用 │  │  │应用 │  │  │应用 │     │
│  │代码 │  │  │代码 │  │  │代码 │     │
│  └─────┘  │  └─────┘  │  └─────┘     │
│  ┌─────┐  │  ┌─────┐  │  ┌─────┐     │
│  │依赖 │  │  │依赖 │  │  │依赖 │     │
│  │库   │  │  │库   │  │  │库   │     │
│  └─────┘  │  └─────┘  │  └─────┘     │
└───────────┴───────────┴──────────────┘
  • 每个容器就像一艘集装箱船上的标准集装箱
  • 每个集装箱(容器)都包含特定的货物(应用程序)
  • 无论船(服务器)是什么类型,集装箱都能被正确装卸和运输
  • 集装箱之间相互隔离,互不影响

💡 小贴士:Docker容器共享宿主机的操作系统内核,而虚拟机需要运行完整的操作系统,因此容器更轻量、启动更快。

1.2 Docker架构

Docker采用客户端-服务端架构,主要组件包括:

┌───────────────────────────────────────────────────────────────┐
│                        宿主机                                 │
├───────────────────┬───────────────────────────┬───────────────┤
│      Client       │        Docker Daemon    │    Registry   │
│  (docker命令行)   │  (dockerd, containerd)  │  (Docker Hub) │
└─────────┬─────────┴─────────────────┬───────┴───────┬───────┘│                           │               │▼                           ▼               ▼
┌─────────────────┐        ┌──────────────────┐ ┌──────────────┐
│    Docker CLI   │        │ Container Runtime│ │  Image Store │
└─────────────────┘        └──────────────────┘ └──────────────┘
  • Docker CLI:命令行界面,用于向Docker守护进程发送命令
  • Docker Daemon:Docker守护进程,负责管理镜像、容器、网络和卷等
  • Container Runtime:容器运行时(如containerd),负责运行容器
  • Registry:镜像仓库,用于存储和分发Docker镜像

1.3 Docker vs 虚拟机

特性Docker容器虚拟机
架构直接运行在宿主机操作系统上运行在Hypervisor上
资源占用轻量级(MB级别)重量级(GB级别)
启动速度秒级分钟级
隔离性进程级隔离完整操作系统隔离
性能几乎无损耗有性能损耗

关键区别

┌───────────────────┐      ┌───────────────────┐
│     虚拟机        │      │     Docker        │
├─────────┬─────────┤      ├─────────┬─────────┤
│ Guest OS│  应用   │      │  应用   │  依赖   │
├─────────┼─────────┤      ├─────────┼─────────┤
│ Hypervisor        │      │ Docker  │         │
├─────────┼─────────┤      ├─────────┼─────────┤
│ Host OS │         │      │ Host OS │         │
└─────────┴─────────┘      └─────────┴─────────┘

1.4 Docker核心概念

镜像(Image)
  • Docker的"蓝图"或"模板"
  • 包含运行应用程序所需的一切
  • 只读层,不可修改
容器(Container)
  • 镜像的运行实例
  • 镜像 + 可写层
  • 应用程序实际运行的地方
仓库(Repository)
  • 存储Docker镜像的地方
  • 最常用的公共仓库:Docker Hub

Docker Hub上最受欢迎的镜像:

  • 数据库
    • PostgreSQL(1B+ pulls,14502 stars)
    • MySQL(1B+ pulls,15899 stars)
    • MongoDB(1B+ pulls,10623 stars)
  • 开发环境
    • Node.js(1B+ pulls,13983 stars)
    • OpenJDK(1B+ pulls,4067 stars)
    • Golang(1B+ pulls,5063 stars)
    • PHP(1B+ pulls,7790 stars)
Dockerfile
  • 创建Docker镜像的"配方"
  • 包含一系列指令

💡 避坑指南:镜像是静态的,容器是动态的。你可以从同一个镜像启动多个容器实例。

1.5 Docker Engine更新渠道

Docker Engine提供两种更新渠道:

  • Stable(稳定版):经过充分测试的正式发布版本
  • Test(测试版):预发布版本,用于测试新功能

生产环境建议使用Stable渠道,开发环境可考虑使用Test渠道体验新功能。


第二章:安装Docker

2.1 Windows系统安装

  1. 下载Docker Desktop

    • 访问 Docker官网
    • 点击"Download for Windows"
  2. 安装过程

    • 双击下载的安装文件
    • 按照向导提示进行安装
    • 建议勾选"Install required Windows components for WSL 2"
  3. 启动Docker

    • 安装完成后,Docker会自动启动
    • 检查系统托盘,看到鲸鱼图标表示Docker正在运行
  4. 验证安装

    在命令提示符或PowerShell中输入:

    > docker --version
    Docker version 24.0.7, build afdd53b
    

💡 小贴士:Windows 10家庭版需要额外安装WSL 2(Windows Subsystem for Linux 2)。安装后可能需要重启电脑。

许可说明:Docker Desktop 对于个人用户、教育机构和中小型企业是免费的。大型企业(超过250名员工或年收入超过1000万美元)需要购买商业许可。

2.2 macOS系统安装

  1. 下载Docker Desktop

    • 访问 Docker官网
    • 点击"Download for Mac"
  2. 安装过程

    • 双击下载的.dmg文件
    • 将Docker图标拖到Applications文件夹
    • 在Applications中双击Docker.app启动
  3. 验证安装

    在终端中输入:

    > docker --version
    Docker version 24.0.7, build afdd53b
    

2.3 Linux系统安装(Ubuntu 22.04示例)

# 1. 更新软件包索引
> sudo apt update# 2. 安装必要的软件包
> sudo apt install apt-transport-https ca-certificates curl software-properties-common# 3. 添加Docker官方GPG密钥
> curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg# 4. 设置Docker稳定版仓库
> echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null# 5. 安装Docker引擎
> sudo apt update
> sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin# 6. 验证Docker是否正确安装
> sudo docker run hello-world

💡 避坑指南:安装后,普通用户无法直接运行Docker命令。解决方法:

> sudo usermod -aG docker $USER
> newgrp docker  # 或者重启终端

注意:以上以Ubuntu为例,其他Linux发行版的安装命令请参考Docker官方安装文档。

2.4 Docker Desktop功能详解

Docker Desktop不仅包含Docker Engine,还提供了一系列增强功能:

  • Docker Engine:强大的容器运行时,提供高性能和可靠的容器化应用支持
  • Docker CLI:灵活的命令行界面,提供精确的容器控制
  • Docker Compose:简化多容器应用的管理
  • Docker Build:简化容器镜像构建过程
  • Docker Kubernetes:内置Kubernetes支持,无需外部集群即可本地开发
  • Volume Management:有效的数据管理解决方案
  • Synchronized File Shares:实时同步主机和容器间的文件
  • Docker Debug:高级故障排除工具
  • Hardened Docker Desktop:增强的容器隔离和安全性
  • VDI Support:虚拟桌面基础设施集成
  • Docker Private Extensions Marketplace:定制化扩展功能

2.5 验证安装

无论哪个平台,安装完成后运行以下命令:

> docker run hello-world

如果看到类似以下输出,说明Docker安装成功:

Hello from Docker!
This message shows that your installation appears to be working correctly.

💡 小贴士docker --version 只验证了客户端。docker run hello-world 验证整个Docker引擎(客户端+守护进程)都已正确安装并运行。


第三章:Docker基础操作

3.1 第一个Docker容器

让我们运行一个简单的Nginx Web服务器:

> docker run -d -p 8080:80 --name my-nginx nginx

参数解释

  • -d:后台运行容器(detached模式)
  • -p 8080:80:将宿主机的8080端口映射到容器的80端口
  • --name my-nginx:给容器命名
  • nginx:要使用的镜像名称(如果本地不存在,Docker会自动从Docker Hub拉取官方nginx镜像)

💡 小贴士docker run 命令实际上融合了 docker pull(如果镜像不存在)、docker createdocker start 三个步骤。

验证

  1. 打开浏览器
  2. 访问 http://localhost:8080
  3. 应该看到Nginx欢迎页面

3.2 常用Docker命令

容器管理
# 列出正在运行的容器
> docker ps# 列出所有容器(包括停止的)
> docker ps -a# 停止一个容器
> docker stop my-nginx# 启动一个已停止的容器
> docker start my-nginx# 重启容器
> docker restart my-nginx# 删除容器
> docker rm my-nginx# 查看容器日志
> docker logs my-nginx# 进入正在运行的容器
> docker exec -it my-nginx bash# 查看Docker磁盘使用情况
> docker system df
镜像管理
# 列出本地镜像
> docker images# 拉取镜像(从Docker Hub)
> docker pull ubuntu:22.04# 删除镜像
> docker rmi nginx# 构建镜像(基于Dockerfile)
> docker build -t my-app:1.0 .

💡 避坑指南:删除正在运行的容器前,需要先停止它:docker stop container_id && docker rm container_id,或者直接使用docker rm -f container_id强制删除。

3.3 实战练习:运行Python应用

  1. 创建一个简单的Python应用:

    > mkdir python-app
    > cd python-app
    > echo "from http.server import HTTPServer, BaseHTTPRequestHandlerclass SimpleHandler(BaseHTTPRequestHandler):def do_GET(self):self.send_response(200)self.send_header('Content-type', 'text/html')self.end_headers()self.wfile.write(b'Hello from Docker!')if __name__ == '__main__':server = HTTPServer(('0.0.0.0', 8000), SimpleHandler)server.serve_forever()" > app.py
    
  2. 运行Python应用容器:

    > docker run -d -p 8000:8000 -v $(pwd):/app -w /app python:3.11 python app.py
    
  3. 访问 http://localhost:8000 查看结果

命令解释

  • -v $(pwd):/app:将当前目录挂载到容器的/app目录
  • -w /app:设置工作目录为/app
  • python:3.11:使用Python 3.11官方镜像

💡 小贴士:在Windows PowerShell中,$(pwd)应替换为${PWD}

📝 本章练习

  1. 运行一个Ubuntu容器:docker run -it ubuntu bash
  2. 在容器内执行ls /,查看文件系统
  3. 退出容器(输入exit或按Ctrl+D)
  4. 再次运行相同的命令,观察结果有何不同
  5. (挑战)运行一个MySQL容器,使用-e MYSQL_ROOT_PASSWORD=my-secret-pw设置root密码,并使用docker exec命令进入容器验证MySQL是否正常运行

第四章:Dockerfile详解

4.1 什么是Dockerfile?

Dockerfile是一个文本文件,包含了一系列指令,告诉Docker如何构建一个镜像。

4.2 基本Dockerfile结构

让我们创建一个简单的Node.js应用Dockerfile:

# 1. 基础镜像
FROM node:18# 2. 设置工作目录
WORKDIR /app# 3. 复制package.json(先单独复制,利用Docker缓存)
COPY package.json .# 4. 安装依赖
RUN npm install# 5. 复制应用代码
COPY . .# 6. 暴露端口
EXPOSE 3000# 7. 定义启动命令
CMD ["npm", "start"]

4.3 关键指令详解

指令用途示例
FROM指定基础镜像FROM ubuntu:22.04
ARG定义构建参数ARG NODE_VERSION=18
FROM node:${NODE_VERSION}
RUN在镜像中执行命令RUN apt-get update && apt-get install -y python3
COPY复制文件到镜像COPY app.py /app/
ADD类似COPY,但支持URL和自动解压ADD https://example.com/file.tar.gz /app/
WORKDIR设置工作目录WORKDIR /app
ENV设置环境变量ENV NODE_ENV=production
EXPOSE声明容器运行时监听的端口EXPOSE 80
CMD容器启动时执行的命令CMD ["python", "app.py"]
ENTRYPOINT容器启动时执行的命令(不可覆盖)ENTRYPOINT ["java", "-jar", "/app.jar"]

4.4 构建和运行自定义镜像

  1. 创建Node.js应用:

    > mkdir node-app
    > cd node-app
    > npm init -y
    > echo 'const express = require("express");
    const app = express();
    app.get("/", (req, res) => res.send("Hello from Docker!"));
    app.listen(3000, () => console.log("Server running on port 3000"));' > index.js
    
  2. 创建Dockerfile(内容如上所述)

  3. 构建镜像:

    > docker build -t my-node-app:1.0 .
    
  4. 运行容器:

    > docker run -d -p 3000:3000 --name node-app my-node-app:1.0
    
  5. 访问 http://localhost:3000

💡 避坑指南:Docker构建时,默认使用当前目录作为上下文。确保Dockerfile在项目根目录,且不包含不必要的大文件(使用.dockerignore)。

4.5 Docker BuildKit详解

Docker BuildKit是Docker 18.09+引入的下一代构建系统,提供了显著的性能改进和新功能:

启用BuildKit

# 临时启用
> DOCKER_BUILDKIT=1 docker build .# 永久启用(修改daemon.json)
{"features": {"buildkit": true}
}

BuildKit优势

  • 更快的构建速度:并行构建和缓存优化
  • 更好的安全性:隔离的构建环境
  • 高级功能
    # 语法声明(使用BuildKit特有功能)
    # syntax=docker/dockerfile:1.3# SSH转发
    FROM alpine
    RUN --mount=type=ssh ssh example.com ls# 构建时缓存
    RUN --mount=type=cache,target=/root/.cache/go-build go build .# 秘密管理
    RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
    

💡 小贴士:Docker 23.0+默认启用BuildKit,可以自动清理中间层,进一步减小镜像大小。

4.6 优化Docker镜像大小

1. 使用合适的基镜像
  • 优先使用alpine版本(更小)
  • 例如:node:18-alpinenode:18 小约200MB
2. 多阶段构建
# 构建阶段
FROM node:18 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production  # 使用ci确保依赖版本确定性
COPY . .
RUN npm run build# 运行阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package.json .
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]
3. 减少镜像层数
# 不推荐
RUN apt-get update
RUN apt-get install -y package1 package2# 推荐(合并为一条命令)
RUN apt-get update && apt-get install -y \package1 \package2 \&& rm -rf /var/lib/apt/lists/*
4. 清理不必要的文件
RUN npm install && npm cache clean --force
5. 使用.dockerignore文件

创建.dockerignore文件,排除不需要的文件:

node_modules
.git
*.log
.env
Dockerfile
.dockerignore

📝 本章练习

  1. 为你的Python应用创建Dockerfile
  2. 构建并运行镜像
  3. 使用docker image inspect查看镜像详情
  4. (挑战)尝试使用多阶段构建优化你的Docker镜像

第五章:Docker Compose

5.1 什么是Docker Compose?

Docker Compose是用于定义和运行多容器Docker应用程序的工具。通过一个YAML文件配置应用程序服务,然后使用一个命令创建并启动所有服务。

5.2 安装Docker Compose

  • Windows/macOS:Docker Desktop已包含Compose
  • Linux:Docker 20.10+已内置Compose插件,无需单独安装

💡 小贴士:在Linux上,旧版Docker需要单独安装Compose:

> sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
> sudo chmod +x /usr/local/bin/docker-compose

5.3 Docker Compose Specification

Docker Compose已发展为Compose Specification,这是云原生计算基金会(CNCF)的项目,旨在标准化多容器应用的定义。最新版本已移除version字段要求:

services:web:image: nginxports:- "8080:80"db:image: postgresenvironment:POSTGRES_PASSWORD: example

这种格式与Docker Compose、Podman Compose和Kubernetes的Kompose兼容,提供更广泛的互操作性。

5.4 docker-compose.yml结构

version: '3.8'  # 指定Compose文件格式版本services:  # 定义所有服务web:  # 服务名称image: nginx:latest  # 使用的镜像ports:- "8080:80"  # 端口映射volumes:- ./html:/usr/share/nginx/html  # 卷挂载db:image: mysql:8.0environment:MYSQL_ROOT_PASSWORD: example  # 设置环境变量MYSQL_DATABASE: mydbvolumes:- db_data:/var/lib/mysql  # 命名卷volumes:  # 定义卷db_data:

💡 小贴士:对于新项目,可以直接使用Compose Specification(即直接写 services:),这代表最新标准。工具会自动兼容。

5.5 实战:部署WordPress应用

  1. 创建项目目录:

    > mkdir wordpress-app
    > cd wordpress-app
    
  2. 创建docker-compose.yml文件:

    version: '3.8'services:db:image: mysql:8.0volumes:- db_data:/var/lib/mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: somewordpressMYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: wordpresshealthcheck:  # 添加健康检查test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]interval: 10stimeout: 5sretries: 5wordpress:depends_on:db:condition: service_healthy  # 确保数据库真正就绪image: wordpress:latestports:- "8000:80"restart: alwaysenvironment:WORDPRESS_DB_HOST: db:3306WORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: wordpressWORDPRESS_DB_NAME: wordpress
    volumes:db_data:
    
  3. 启动应用:

    > docker-compose up -d
    
  4. 访问 http://localhost:8000 开始WordPress安装

  5. 常用Compose命令:

    # 启动所有服务
    > docker-compose up -d# 停止所有服务
    > docker-compose down# 查看服务日志
    > docker-compose logs -f# 重启服务
    > docker-compose restart wordpress# 构建/重新构建服务
    > docker-compose build
    

⚠️ 重要提示depends_on只控制启动顺序,不等待服务真正就绪。对于需要等待数据库初始化的应用,必须实现健康检查并使用condition: service_healthy,这是生产环境的最佳实践。

📝 本章练习

  1. 创建一个包含Nginx和Alpine的Compose文件
  2. 配置Nginx服务监听8080端口
  3. 使用docker-compose up启动服务
  4. 访问 http://localhost:8080 验证
  5. (挑战)为Nginx配置自定义HTML内容(使用卷挂载)

第六章:Docker网络

6.1 Docker网络模式

模式描述使用场景
bridge默认模式,容器通过虚拟网桥连接单机上多个容器通信
host容器直接使用宿主机网络需要高性能网络的应用
none容器没有网络完全隔离的容器
overlay跨多个Docker守护进程的网络Docker Swarm集群

6.2 创建自定义网络

# 创建自定义桥接网络
> docker network create my-network# 在自定义网络中运行容器
> docker run -d --name web --network my-network nginx
> docker run -it --name alpine --network my-network alpine sh# 在alpine容器中测试与web容器的连接
/ # ping web

6.3 容器间通信

场景:前端应用需要连接后端API

  1. 创建自定义网络:

    > docker network create app-network
    
  2. 启动后端服务:

    > docker run -d --name backend --network app-network -p 5000:5000 my-backend-image
    
  3. 启动前端服务:

    > docker run -d --name frontend --network app-network -p 3000:3000 \-e API_URL=http://backend:5000 my-frontend-image
    
  4. 前端容器可以通过http://backend:5000访问后端服务

6.4 网络排查

# 查看所有网络
> docker network ls# 查看特定网络的详细信息
> docker network inspect app-network# 查看容器的网络配置
> docker inspect frontend | grep IPAddress

💡 避坑指南:Docker容器使用服务名称作为主机名进行通信。确保在代码中使用服务名称(如http://backend:5000)而不是IP地址。

📝 本章练习

  1. 创建一个自定义网络test-net
  2. 在该网络中运行两个Nginx容器
  3. 从一个容器ping另一个容器
  4. 尝试不使用自定义网络,直接通过容器名通信(会失败)
  5. (挑战)创建一个包含前端、后端和数据库的Compose文件,并配置正确的网络

第七章:数据持久化

7.1 为什么需要数据持久化?

默认情况下,容器停止后,容器内的所有数据都会丢失。对于数据库等需要持久存储的应用,我们需要将数据存储在容器外部。

7.2 三种数据管理方式

类型描述适用场景
数据卷(Volumes)由Docker管理的存储区域生产环境,最佳实践
绑定挂载(Bind Mounts)将宿主机目录直接挂载到容器开发环境,需要实时编辑文件
tmpfs挂载仅存储在内存中临时数据,敏感数据

7.3 使用数据卷

# 创建命名卷
> docker volume create my-volume# 查看所有卷
> docker volume ls# 使用卷运行容器
> docker run -d -v my-volume:/app/data --name my-container nginx# 查看卷详情
> docker volume inspect my-volume# 清理未使用的卷
> docker volume prune

7.4 数据卷备份与恢复

数据卷备份

# 创建备份容器
> docker run --rm -v my-volume:/volume -v $(pwd):/backup alpine \tar cvf /backup/backup.tar -C /volume . 

数据卷恢复

# 创建新卷
> docker volume create restore-volume# 恢复数据
> docker run --rm -v restore-volume:/volume -v $(pwd):/backup alpine \tar xvf /backup/backup.tar -C /volume

生产环境建议

  • 使用定时任务定期备份关键数据卷
  • 将备份存储到安全位置(如云存储)
  • 测试恢复流程,确保备份有效
  • 考虑使用专业备份工具如Velero(Kubernetes环境)

7.5 实战:MySQL数据持久化

# 创建数据卷
> docker volume create mysql-data# 运行MySQL容器
> docker run -d \-v mysql-data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORD=my-secret-pw \--name mysql \mysql:8.0

即使容器被删除,数据仍然保留在mysql-data卷中。

💡 避坑指南:数据卷的路径在宿主机上通常是/var/lib/docker/volumes/,但不应直接操作这些文件,应通过Docker命令管理。

7.6 使用绑定挂载进行开发

# 将当前目录挂载到容器的/app目录
> docker run -d \-v $(pwd):/app \-w /app \node:18 \npm start

开发优势

  • 代码修改后无需重新构建镜像
  • 实时看到更改效果
  • 适合前端开发和热重载

📝 本章练习

  1. 创建一个数据卷app-data
  2. 运行一个Nginx容器,将/usr/share/nginx/html挂载到该卷
  3. 在卷中创建一个index.html文件
  4. 访问Nginx服务,验证内容
  5. (挑战)使用绑定挂载开发一个简单的Node.js应用,实现代码热重载

第八章:实战项目 - 部署一个完整的Web应用

8.1 项目结构

my-app/
├── frontend/       # 前端代码(React)
├── backend/        # 吘端代码(Node.js)
├── docker-compose.yml
└── README.md

8.2 前端Dockerfile

# frontend/Dockerfile
# 构建阶段
FROM node:18 as build
WORKDIR /app
COPY package*.json ./
RUN npm ci  # 使用ci确保依赖版本确定性
COPY . .
RUN npm run build# 生产阶段
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

8.3 后端Dockerfile

# backend/Dockerfile
FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production  # 生产环境只安装生产依赖
COPY . .
EXPOSE 5000
CMD ["node", "server.js"]

8.4 docker-compose.yml

version: '3.8'services:frontend:build: context: ./frontendlabels:- "org.opencontainers.image.revision=${GIT_COMMIT:-latest}"  # 注入git commit信息ports:- "3000:80"depends_on:backend:condition: service_healthynetworks:- app-networkbackend:build: context: ./backendlabels:- "org.opencontainers.image.revision=${GIT_COMMIT:-latest}"ports:- "5000:5000"environment:DB_HOST: dbDB_USER: userDB_PASS: passworddepends_on:db:condition: service_healthynetworks:- app-networkhealthcheck:test: ["CMD", "curl", "-f", "http://localhost:5000/health"]interval: 30stimeout: 10sretries: 3db:image: postgres:15environment:POSTGRES_USER: userPOSTGRES_PASSWORD: passwordPOSTGRES_DB: mydbvolumes:- pgdata:/var/lib/postgresql/datanetworks:- app-networkhealthcheck:test: ["CMD-SHELL", "pg_isready -U user"]interval: 10stimeout: 5sretries: 5networks:app-network:driver: bridgevolumes:pgdata:

💡 小贴士condition: service_healthy确保服务真正就绪后再启动依赖服务,避免启动顺序问题。通过labels注入git commit信息便于镜像追踪。

8.5 部署步骤

  1. 克隆项目:

    > git clone https://github.com/yourusername/my-app.git
    > cd my-app
    
  2. 启动应用:

    > docker-compose up -d --build
    
  3. 访问应用:

    • 前端:http://localhost:3000
    • 后端API:http://localhost:5000/api
  4. 查看日志:

    > docker-compose logs -f
    
  5. 停止应用:

    > docker-compose down
    

📝 本章练习

  1. 创建一个简单的前后端分离应用
  2. 为前后端分别编写Dockerfile
  3. 创建docker-compose.yml文件,配置服务依赖和网络
  4. 实现健康检查,确保服务正确启动
  5. (挑战)添加Redis服务,并配置前后端使用Redis

第九章:常见问题与解决方案

9.1 容器无法启动

问题:容器启动后立即退出
原因:主进程执行完毕退出
解决方案

  • 确保CMDENTRYPOINT指定的是长期运行的进程
  • 使用-it参数运行容器进行调试:
    > docker run -it --rm my-image sh
    

💡 避坑指南:容器必须有一个前台进程才能保持运行。如果运行的是后台服务,需要使用-d参数或确保命令保持前台运行。

9.2 端口冲突

问题

Error response from daemon: driver failed programming external connectivity on endpoint...: 
bind: address already in use.

解决方案

  • 更换宿主机端口:
    > docker run -p 8081:80 nginx
    
  • 停止占用端口的进程:
    # Linux/Mac
    > lsof -i :8080# Windows
    > netstat -ano | findstr :8080
    

9.3 镜像拉取失败

问题

Error response from daemon: Get https://registry-1.docker.io/v2/: 
net/http: request canceled while waiting for connection

解决方案

  • 检查网络连接
  • 配置Docker镜像加速器(针对中国用户):
    1. 创建或修改 /etc/docker/daemon.json
    2. 添加:
      {"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com"]
      }
      
    3. 重启Docker:sudo systemctl restart docker

💡 小贴士:Docker Desktop用户可以在设置中直接配置镜像加速器。常用的镜像加速器包括:

  • 阿里云容器镜像服务(需登录获取个人加速地址)
  • 网易云:https://hub-mirror.c.163.com
  • 中国科学技术大学:https://docker.mirrors.ustc.edu.cn

9.4 容器内无法访问网络

问题:容器内无法ping通外部网络
解决方案

  • 检查DNS配置:
    > docker run --dns=8.8.8.8 -it ubuntu ping google.com
    
  • 检查防火墙设置
  • 重置Docker网络:
    > docker network prune
    

9.5 清理磁盘空间

问题:Docker占用大量磁盘空间
解决方案

# 清理停止的容器
> docker container prune# 清理未使用的镜像
> docker image prune# 清理未使用的网络
> docker network prune# 清理所有未使用的资源(包括构建缓存)
> docker system prune -a# 查看磁盘使用情况
> docker system df

💡 避坑指南:定期清理可以避免磁盘空间不足问题。建议在CI/CD管道中添加清理步骤。

📝 本章练习

  1. 故意制造一个端口冲突,然后解决它
  2. 模拟镜像拉取失败,配置镜像加速器
  3. 创建一个无法启动的容器,使用-it调试
  4. (挑战)编写一个脚本,每天自动清理Docker资源

第十章:最佳实践与安全建议

10.1 镜像构建最佳实践

  1. 使用.dockerignore文件

    node_modules
    .git
    *.log
    .env
    Dockerfile
    .dockerignore
    
  2. 合理排序Dockerfile指令

    • 将变化较少的指令放在前面
    • 例如:先COPY package.json,再RUN npm install,最后COPY其他文件
  3. 使用多阶段构建

    • 减小最终镜像大小
    • 避免将构建工具包含在生产镜像中
  4. 指定软件包版本

    RUN apt-get install -y python3=3.10.6-1ubuntu0.1
    
  5. 镜像分层原理

    • Docker镜像由多层只读层组成
    • 每条Dockerfile指令创建一个新层
    • 利用缓存机制:当某一层发生变化时,其后的所有层都需要重新构建
    • 合并相关操作到同一层可减少镜像层数

10.2 安全最佳实践

  1. 不要以root用户运行容器

    FROM node:18
    RUN groupadd -r appuser && useradd -r -g appuser appuser
    USER appuser
    
  2. 定期更新基础镜像

    > docker pull node:18
    > docker build -t my-app:latest .
    
  3. 扫描镜像漏洞

    # 需要先登录Docker Hub
    > docker login
    > docker scan my-app:latest# 或者使用开源工具如Trivy
    > trivy image --severity CRITICAL,HIGH my-app:latest
    
  4. 限制容器资源

    > docker run -d \--memory=512m \--cpus=1.5 \my-app
    
  5. 不要在镜像中存储敏感信息

    • 使用环境变量或Docker secrets
    • 通过docker run -edocker-compose的environment设置
  6. 使用非最新版本的具体标签

    • 使用node:18.18.0-alpine 而不是 node:18-alpinenode:latest
    • 确保部署的确定性和安全性
  7. 最小权限原则

    > docker run --cap-drop ALL --cap-add NET_BIND_SERVICE my-app
    
  8. Docker内容信任(Docker Content Trust)

    # 启用内容信任
    > export DOCKER_CONTENT_TRUST=1# 签名并推送镜像
    > docker trust sign myimage:tag# 验证签名
    > docker trust inspect myimage:tag
    
  9. 安全上下文配置

    services:app:# ...security_opt:- no-new-privileges:trueread_only: truecap_drop:- ALLcap_add:- NET_BIND_SERVICE
    

10.3 生产环境部署建议

  1. 使用编排工具

    • Docker Swarm(内置)
    • Kubernetes(更强大,适合大型部署)
  2. 实现健康检查

    HEALTHCHECK --interval=30s --timeout=3s \CMD curl -f http://localhost/ || exit 1
    
  3. 集中式日志管理

    • 使用ELK栈(Elasticsearch, Logstash, Kibana)
    • 或Docker日志驱动:docker run --log-driver=json-file ...
  4. 监控与告警

    • Prometheus + Grafana
    • cAdvisor(容器资源监控)
  5. Docker Desktop的Kubernetes集成
    Docker Desktop内置了Kubernetes支持,无需额外安装即可在本地开发环境中使用Kubernetes:

    1. 启用Kubernetes

      • Windows/macOS:Docker Desktop设置 → Kubernetes → 勾选"Enable Kubernetes"
      • Linux:需单独安装
    2. 验证安装

      > kubectl cluster-info
      Kubernetes control plane is running at https://kubernetes.docker.internal:6443
      
    3. 使用Kubernetes

      > kubectl create deployment nginx --image=nginx
      > kubectl expose deployment nginx --port=80
      > kubectl get pods
      

    Docker Desktop的Kubernetes支持包括:

    • 单节点集群(开发使用)
    • 与Docker Compose的集成
    • 简单的UI管理
    • 本地开发的理想环境

💡 避坑指南:生产环境应避免使用latest标签,而应使用具体的版本号,确保可重复部署。

📝 本章练习

  1. 为你的应用Dockerfile添加非root用户
  2. 添加健康检查指令
  3. 限制容器的内存和CPU使用
  4. (挑战)使用Docker扫描工具检查你的镜像漏洞

第十一章:进阶主题

11.1 Docker Swarm简介

Docker Swarm是Docker原生的集群管理和编排工具。

基本概念

  • Node:集群中的Docker主机
  • Manager:管理集群的节点
  • Worker:执行任务的节点
  • Service:在集群中运行的应用

创建Swarm集群

# 初始化Swarm(作为Manager)
> docker swarm init# 获取加入令牌
> docker swarm join-token worker# 在其他节点上加入Swarm
> docker swarm join --token <token> <manager-ip>:2377

部署服务

> docker service create --replicas 3 -p 80:80 --name my-web nginx

11.2 Kubernetes简介

Kubernetes(简称K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用。

核心概念

  • Pod:Kubernetes中最小的部署单元,可包含一个或多个容器
  • Deployment:管理Pod的声明式更新
  • Service:定义Pod的访问策略
  • Namespace:资源的虚拟集群

简单示例

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.14.2ports:- containerPort: 80

应用配置:

> kubectl apply -f deployment.yaml

11.3 CI/CD集成

GitHub Actions示例

name: Docker Image CIon:push:branches: [ main ]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4with:fetch-depth: 0  # 获取所有历史记录,便于生成标签- name: Set up Docker Buildxuses: docker/setup-buildx-action@v3- name: Login to DockerHubuses: docker/login-action@v2with:username: ${{ secrets.DOCKERHUB_USERNAME }}password: ${{ secrets.DOCKERHUB_TOKEN }}- name: Extract metadata for Dockerid: metauses: docker/metadata-action@v5with:images: user/apptags: |type=shatype=ref,event=branchtype=ref,event=prtype=semver,pattern={{version}}type=semver,pattern={{major}}.{{minor}}- name: Build and pushuses: docker/build-push-action@v5with:context: .push: truetags: ${{ steps.meta.outputs.tags }}labels: ${{ steps.meta.outputs.labels }}cache-from: type=ghacache-to: type=gha,mode=max

💡 小贴士:Docker 23.0+引入了Buildx Build Cache,可以显著加速CI/CD中的镜像构建过程。使用GitHub Actions的缓存功能可以进一步提升构建效率。

11.4 Docker Swarm和Kubernetes对比

特性Docker SwarmKubernetes
学习曲线简单,易于上手陡峭,需要更多学习
安装配置简单,Docker内置复杂,需要单独安装
功能丰富度基础功能非常丰富,功能全面
社区支持中等非常活跃
适用场景中小型应用,简单部署大型应用,复杂部署
扩展性有限非常强大
自动伸缩基础支持高级支持
滚动更新支持高级支持
健康检查基础支持高级支持
网络策略基础支持高级支持

选择建议

  • 如果是小型团队或简单应用,Docker Swarm足够使用
  • 如果需要高级功能或大规模部署,Kubernetes是更好的选择
  • 对于本地开发,Docker Desktop内置的Kubernetes支持是理想选择

📝 本章练习

  1. 初始化一个Docker Swarm集群
  2. 部署一个简单的服务
  3. 扩展服务的副本数
  4. (挑战)尝试将你的应用部署到Kubernetes集群

附录A:Docker命令速查表

基础命令

命令描述
docker ps列出正在运行的容器
docker ps -a列出所有容器
docker images列出本地镜像
docker run [OPTIONS] IMAGE [COMMAND]运行容器
docker stop CONTAINER停止容器
docker start CONTAINER启动容器
docker rm CONTAINER删除容器
docker rmi IMAGE删除镜像
docker logs CONTAINER查看容器日志
docker exec -it CONTAINER COMMAND在运行的容器中执行命令

高级命令

命令描述
docker build -t TAG .构建镜像
docker-compose up启动Compose服务
docker network ls列出网络
docker volume ls列出数据卷
docker system df查看Docker磁盘使用
docker system prune清理未使用的资源
docker inspect CONTAINER查看容器详细信息
docker stats实时资源使用情况
docker events监听Docker事件
docker diff CONTAINER查看容器文件系统变化

附录B:推荐学习资源

📚 官方文档

  • Docker官方文档
  • Docker Hub
  • Compose Specification

📺 视频教程

  • Docker入门教程(B站)
  • Docker & Kubernetes: The Practical Guide (Udemy)

💻 实践平台

  • Play with Docker
  • Katacoda Docker场景

📖 书籍推荐

  • 《Docker技术入门与实战》
  • 《Kubernetes权威指南》

🔧 实用工具

  • Trivy - 容器漏洞扫描工具
  • Dive - 镜像层分析工具
  • Lens - Kubernetes IDE
  • Portainer - Docker管理UI

结语:继续你的Docker之旅

恭喜你完成了Docker入门学习!现在你已经掌握了Docker的核心概念和实用技能,可以开始在自己的项目中应用Docker了。

下一步建议

  1. 实践项目:尝试将你现有的一个应用容器化
  2. 深入学习
    • 阅读Docker官方文档
    • 学习Kubernetes基础知识
  3. 加入社区
    • Docker官方论坛
    • Stack Overflow的docker标签
    • 本地Docker/Kubernetes用户组

记住,最好的学习方式是动手实践!从简单开始,逐步增加复杂度,很快你就会成为Docker高手。

祝你在容器化旅程中一切顺利! 🐳


📝 附:学习进度检查表

✅ 已完成❌ 未完成📅 计划完成日期
安装Docker
运行第一个容器
理解Dockerfile
使用Docker Compose
配置Docker网络
实现数据持久化
部署完整Web应用
解决常见问题
应用最佳实践
探索进阶主题

填写你的学习计划,跟踪进度!

http://www.xdnf.cn/news/20191.html

相关文章:

  • 如何在路由器上配置DHCP服务器?
  • 本体论中的公理与规则——从经典逻辑到神经符号融合的演进
  • Hive on Tez/Spark 执行引擎对比与优化
  • AI浪潮下,人类创造力的“危”与“机”
  • 2026届大数据毕业设计选题推荐-基于大数据旅游数据分析与推荐系统 爬虫数据可视化分析
  • JAVA基本文件操作
  • 【74页PPT】MES简介(附下载方式)
  • TensorFlow 面试题及详细答案 120道(101-110)-- 底层原理与扩展
  • C++笔记之软件设计原则总结
  • Lua > Mac Mini M4安装openresty
  • 基于Transformer 实现车辆检测与车牌识别(一)
  • disable CASCADE主键失败 ORA-2297 And ORA-2433
  • MCAP :机器人数据容器的全面实践指南
  • 区块链是什么
  • UE5 图表、函数与宏的区别与选择(蓝图折叠功能详解)
  • 【iOS】push 和 present
  • 什么时候用no,什么时候用non,什么时候用not?
  • 京东商品属性API数据解析:颜色、尺寸与材质
  • 【代码随想录算法训练营——Day4】链表——24.两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题02.07.链表相交、142.环形链表II
  • 操作系统基本概念.1
  • Day 47 注意力热图可视化
  • 工作后的总结和反思4
  • SQL 入门指南:排序与分页查询(ORDER BY 多字段排序、LIMIT 分页实战)
  • 使用Shell脚本实现Linux系统资源监控邮件告警
  • 永磁同步电机 FOC 控制中 d、q 轴杂谈与角度偏移影响
  • 使用Ansible自动化部署Hadoop集群(含源码)--环境准备
  • 【Android】ViewPager2结合Fragment实现多页面滑动切换
  • 百度竞价推广:搜索竞价信息流推广代运营
  • ElementUI之Upload 上传的使用
  • C++语法之--多态