欢迎光临
我们一直在努力

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

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

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

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

学习路径图:

#mermaid-svg-UV87x2eTQ78POaRx {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-UV87x2eTQ78POaRx .error-icon{fill:#552222;}#mermaid-svg-UV87x2eTQ78POaRx .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UV87x2eTQ78POaRx .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-UV87x2eTQ78POaRx .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UV87x2eTQ78POaRx .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UV87x2eTQ78POaRx .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UV87x2eTQ78POaRx .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UV87x2eTQ78POaRx .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UV87x2eTQ78POaRx .marker.cross{stroke:#333333;}#mermaid-svg-UV87x2eTQ78POaRx svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UV87x2eTQ78POaRx .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-UV87x2eTQ78POaRx .cluster-label text{fill:#333;}#mermaid-svg-UV87x2eTQ78POaRx .cluster-label span{color:#333;}#mermaid-svg-UV87x2eTQ78POaRx .label text,#mermaid-svg-UV87x2eTQ78POaRx span{fill:#333;color:#333;}#mermaid-svg-UV87x2eTQ78POaRx .node rect,#mermaid-svg-UV87x2eTQ78POaRx .node circle,#mermaid-svg-UV87x2eTQ78POaRx .node ellipse,#mermaid-svg-UV87x2eTQ78POaRx .node polygon,#mermaid-svg-UV87x2eTQ78POaRx .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UV87x2eTQ78POaRx .node .label{text-align:center;}#mermaid-svg-UV87x2eTQ78POaRx .node.clickable{cursor:pointer;}#mermaid-svg-UV87x2eTQ78POaRx .arrowheadPath{fill:#333333;}#mermaid-svg-UV87x2eTQ78POaRx .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UV87x2eTQ78POaRx .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UV87x2eTQ78POaRx .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-UV87x2eTQ78POaRx .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-UV87x2eTQ78POaRx .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UV87x2eTQ78POaRx .cluster text{fill:#333;}#mermaid-svg-UV87x2eTQ78POaRx .cluster span{color:#333;}#mermaid-svg-UV87x2eTQ78POaRx div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-UV87x2eTQ78POaRx :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

安装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系统安装

  • 下载Docker Desktop:

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

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

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

    在命令提示符或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系统安装

  • 下载Docker Desktop:

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

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

    在终端中输入:

    > docker –version
    Docker version 24.0.7, build afdd53b

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

    # 1. 更新软件包索引
    sudo apt update

    # 2. 安装必要的软件包
    sudo apt install -y docker.io
    # 3.启动 Docker 服务
    sudo service docker start

    # 6. 验证Docker是否正确安装
    > sudo docker run hello-world

    配置国内镜像加速器

    sudo mkdir p /etc/docker
    sudo nano /etc/docker/daemon.json

    插入内容

    {
    "registry-mirrors": [
    "https://docker.1ms.run",
    "https://docker.xuanyuan.me"
    ]
    }

    保存并退出编辑器(在 nano 中按 Ctrl+O 回车保存,Ctrl+X 退出)。 重启 Docker 服务,使配置生效:

    sudo service docker restart

    查看 Docker 信息,确认镜像加速器是否生效:

    docker info

    输出中应包含:

    127.0.0.0/8
    Registry Mirrors:
    https://docker.1ms.run/
    https://docker.xuanyuan.me/
    Live Restore Enabled: false

    测试拉取镜像:

    docker pull helloworld

    如果成功,会显示拉取镜像及运行容器的相关信息运行docker:

    sudo docker run helloworld

    显示信息

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

    💡 避坑指南:安装后,普通用户无法直接运行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 create、docker start 三个步骤。

    验证:

  • 打开浏览器
  • 访问 http://localhost:8080
  • 应该看到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应用

  • 创建一个简单的Python应用:

    > mkdir python-app
    > cd python-app
    > echo "from http.server import HTTPServer, BaseHTTPRequestHandler

    class 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

  • 运行Python应用容器:

    > docker run -d -p 8000:8000 -v $(pwd):/app -w /app python:3.11 python app.py

  • 访问 http://localhost:8000 查看结果

  • 命令解释:

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

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

    📝 本章练习

  • 运行一个Ubuntu容器:docker run -it ubuntu bash
  • 在容器内执行ls /,查看文件系统
  • 退出容器(输入exit或按Ctrl+D)
  • 再次运行相同的命令,观察结果有何不同
  • (挑战)运行一个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=18FROM 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 构建和运行自定义镜像

  • 创建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

  • 创建Dockerfile(内容如上所述)

  • 构建镜像:

    > docker build -t my-node-app:1.0 .

  • 运行容器:

    > docker run -d -p 3000:3000 –name node-app my-node-app:1.0

  • 访问 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-alpine 比 node: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

    📝 本章练习

  • 为你的Python应用创建Dockerfile
  • 构建并运行镜像
  • 使用docker image inspect查看镜像详情
  • (挑战)尝试使用多阶段构建优化你的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: nginx
    ports:
    "8080:80"

    db:
    image: postgres
    environment:
    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.0
    environment:
    MYSQL_ROOT_PASSWORD: example # 设置环境变量
    MYSQL_DATABASE: mydb
    volumes:
    db_data:/var/lib/mysql # 命名卷

    volumes: # 定义卷
    db_data:

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

    5.5 实战:部署WordPress应用

  • 创建项目目录:

    > mkdir wordpress-app
    > cd wordpress-app

  • 创建docker-compose.yml文件:

    version: '3.8'

    services:
    db:
    image: mysql:8.0
    volumes:
    db_data:/var/lib/mysql
    restart: always
    environment:
    MYSQL_ROOT_PASSWORD: somewordpress
    MYSQL_DATABASE: wordpress
    MYSQL_USER: wordpress
    MYSQL_PASSWORD: wordpress
    healthcheck: # 添加健康检查
    test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u$$MYSQL_USER", "-p$$MYSQL_PASSWORD"]
    interval: 10s
    timeout: 5s
    retries: 5

    wordpress:
    depends_on:
    db:
    condition: service_healthy # 确保数据库真正就绪
    image: wordpress:latest
    ports:
    "8000:80"
    restart: always
    environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
    WORDPRESS_DB_NAME: wordpress
    volumes:
    db_data:

  • 启动应用:

    > docker-compose up -d

  • 访问 http://localhost:8000 开始WordPress安装

  • 常用Compose命令:

    # 启动所有服务
    > docker-compose up -d

    # 停止所有服务
    > docker-compose down

    # 查看服务日志
    > docker-compose logs -f

    # 重启服务
    > docker-compose restart wordpress

    # 构建/重新构建服务
    > docker-compose build

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

    📝 本章练习

  • 创建一个包含Nginx和Alpine的Compose文件
  • 配置Nginx服务监听8080端口
  • 使用docker-compose up启动服务
  • 访问 http://localhost:8080 验证
  • (挑战)为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

  • 创建自定义网络:

    > docker network create app-network

  • 启动后端服务:

    > docker run -d –name backend –network app-network -p 5000:5000 my-backend-image

  • 启动前端服务:

    > docker run -d –name frontend –network app-network -p 3000:3000 \\
    -e API_URL=http://backend:5000 my-frontend-image

  • 前端容器可以通过http://backend:5000访问后端服务

  • 6.4 网络排查

    # 查看所有网络
    > docker network ls

    # 查看特定网络的详细信息
    > docker network inspect app-network

    # 查看容器的网络配置
    > docker inspect frontend | grep IPAddress

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

    📝 本章练习

  • 创建一个自定义网络test-net
  • 在该网络中运行两个Nginx容器
  • 从一个容器ping另一个容器
  • 尝试不使用自定义网络,直接通过容器名通信(会失败)
  • (挑战)创建一个包含前端、后端和数据库的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

    开发优势:

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

    📝 本章练习

  • 创建一个数据卷app-data
  • 运行一个Nginx容器,将/usr/share/nginx/html挂载到该卷
  • 在卷中创建一个index.html文件
  • 访问Nginx服务,验证内容
  • (挑战)使用绑定挂载开发一个简单的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: ./frontend
    labels:
    "org.opencontainers.image.revision=${GIT_COMMIT:-latest}" # 注入git commit信息
    ports:
    "3000:80"
    depends_on:
    backend:
    condition: service_healthy
    networks:
    appnetwork

    backend:
    build:
    context: ./backend
    labels:
    "org.opencontainers.image.revision=${GIT_COMMIT:-latest}"
    ports:
    "5000:5000"
    environment:
    DB_HOST: db
    DB_USER: user
    DB_PASS: password
    depends_on:
    db:
    condition: service_healthy
    networks:
    appnetwork
    healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
    interval: 30s
    timeout: 10s
    retries: 3

    db:
    image: postgres:15
    environment:
    POSTGRES_USER: user
    POSTGRES_PASSWORD: password
    POSTGRES_DB: mydb
    volumes:
    pgdata:/var/lib/postgresql/data
    networks:
    appnetwork
    healthcheck:
    test: ["CMD-SHELL", "pg_isready -U user"]
    interval: 10s
    timeout: 5s
    retries: 5

    networks:
    app-network:
    driver: bridge

    volumes:
    pgdata:

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

    8.5 部署步骤

  • 克隆项目:

    > git clone https://github.com/yourusername/my-app.git
    > cd my-app

  • 启动应用:

    > docker-compose up -d –build

  • 访问应用:

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

    > docker-compose logs -f

  • 停止应用:

    > docker-compose down

  • 📝 本章练习

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

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

    9.1 容器无法启动

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

    • 确保CMD或ENTRYPOINT指定的是长期运行的进程
    • 使用-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镜像加速器(针对中国用户):
    • 创建或修改 /etc/docker/daemon.json
    • 添加:{
      "registry-mirrors": [
      "https://docker.mirrors.ustc.edu.cn",
      "https://hub-mirror.c.163.com"
      ]
      }
    • 重启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管道中添加清理步骤。

    📝 本章练习

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

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

    10.1 镜像构建最佳实践

  • 使用.dockerignore文件:

    node_modules
    .git
    *.log
    .env
    Dockerfile
    .dockerignore

  • 合理排序Dockerfile指令:

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

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

    RUN apt-get install -y python3=3.10.6-1ubuntu0.1

  • 镜像分层原理:

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

  • 不要以root用户运行容器:

    FROM node:18
    RUN groupadd -r appuser && useradd -r -g appuser appuser
    USER appuser

  • 定期更新基础镜像:

    > docker pull node:18
    > docker build -t my-app:latest .

  • 扫描镜像漏洞:

    # 需要先登录Docker Hub
    > docker login
    > docker scan my-app:latest

    # 或者使用开源工具如Trivy
    > trivy image –severity CRITICAL,HIGH my-app:latest

  • 限制容器资源:

    > docker run -d \\
    –memory=512m \\
    –cpus=1.5 \\
    my-app

  • 不要在镜像中存储敏感信息:

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

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

    > docker run –cap-drop ALL –cap-add NET_BIND_SERVICE my-app

  • Docker内容信任(Docker Content Trust):

    # 启用内容信任
    > export DOCKER_CONTENT_TRUST=1

    # 签名并推送镜像
    > docker trust sign myimage:tag

    # 验证签名
    > docker trust inspect myimage:tag

  • 安全上下文配置:

    services:
    app:
    # …
    security_opt:
    nonewprivileges:true
    read_only: true
    cap_drop:
    ALL
    cap_add:
    NET_BIND_SERVICE

  • 10.3 生产环境部署建议

  • 使用编排工具:

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

    HEALTHCHECK –interval=30s –timeout=3s \\
    CMD curl -f http://localhost/ || exit 1

  • 集中式日志管理:

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

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

  • 启用Kubernetes:

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

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

  • 使用Kubernetes:

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

  • Docker Desktop的Kubernetes支持包括:

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

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

    📝 本章练习

  • 为你的应用Dockerfile添加非root用户
  • 添加健康检查指令
  • 限制容器的内存和CPU使用
  • (挑战)使用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: nginxdeployment
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: nginx
    template:
    metadata:
    labels:
    app: nginx
    spec:
    containers:
    name: nginx
    image: nginx:1.14.2
    ports:
    containerPort: 80

    应用配置:

    > kubectl apply -f deployment.yaml

    11.3 CI/CD集成

    GitHub Actions示例:

    name: Docker Image CI

    on:
    push:
    branches: [ main ]

    jobs:
    build:
    runs-on: ubuntulatest

    steps:
    uses: actions/checkout@v4
    with:
    fetch-depth: 0 # 获取所有历史记录,便于生成标签

    name: Set up Docker Buildx
    uses: docker/setupbuildxaction@v3

    name: Login to DockerHub
    uses: docker/loginaction@v2
    with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

    name: Extract metadata for Docker
    id: meta
    uses: docker/metadataaction@v5
    with:
    images: user/app
    tags: |
    type=sha
    type=ref,event=branch
    type=ref,event=pr
    type=semver,pattern={{version}}
    type=semver,pattern={{major}}.{{minor}}

    name: Build and push
    uses: docker/buildpushaction@v5
    with:
    context: .
    push: true
    tags: ${{ steps.meta.outputs.tags }}
    labels: ${{ steps.meta.outputs.labels }}
    cache-from: type=gha
    cache-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支持是理想选择

    📝 本章练习

  • 初始化一个Docker Swarm集群
  • 部署一个简单的服务
  • 扩展服务的副本数
  • (挑战)尝试将你的应用部署到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了。

    下一步建议:

  • 实践项目:尝试将你现有的一个应用容器化
  • 深入学习:
    • 阅读Docker官方文档
    • 学习Kubernetes基础知识
  • 加入社区:
    • Docker官方论坛
    • Stack Overflow的docker标签
    • 本地Docker/Kubernetes用户组
  • 记住,最好的学习方式是动手实践!从简单开始,逐步增加复杂度,很快你就会成为Docker高手。

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


    📝 附:学习进度检查表

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

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

    赞(0)
    未经允许不得转载:171主机测评 » Docker入门到精通:从零基础到生产部署
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址