Docker 完全指南:从入门到生产级实践

一篇长文,彻底搞懂 Docker、Compose 与 Swarm

容器技术已经成为现代软件交付的基石。无论是开发者、运维工程师,还是架构师,掌握 Docker 都是必备技能。本文将系统介绍 Docker 的核心概念、多容器编排、集群管理,以及从开发到生产的最佳实践。


一、Docker 是什么?为什么需要它?

Docker 是一个开源的容器化平台,允许将应用程序及其所有依赖(库、配置文件、环境变量等)打包成一个轻量级、可移植的容器。容器与底层操作系统解耦,可以在任何支持 Docker 的环境中一致地运行。

核心思想:一次构建,随处运行。

与传统虚拟机的对比

特性 Docker 容器 传统虚拟机
隔离级别 进程级(共享宿主机内核) 硬件虚拟化(完全隔离)
启动时间 毫秒级 秒级到分钟级
磁盘占用 MB 级 GB 级
内存开销 仅容器进程所需 Hypervisor + 客户机 OS
性能损耗 接近原生 有一定损耗
安全隔离 较弱 较强

选择建议:容器适合微服务、开发测试、CI/CD 等需要轻量快速部署的场景;虚拟机适合强隔离、多租户、运行不同类型操作系统的场景。


二、Docker Compose:多容器的统一管家

当需要同时运行多个容器(比如 Web 服务、数据库、缓存、消息队列)时,手动通过 docker run 逐个启动容器存在诸多不便,主要体现在以下方面:

1)需要单独创建容器网络

2)必须严格把控容器启动顺序

3)需逐个配置环境变量参数

4)要分别设置数据卷挂载

Docker Compose 正是为解决这个问题而生的。它是 Docker 官方推出的单机多容器编排工具 。你只需用一个 docker-compose.yml 文件定义所有服务,然后一条命令就能启动整个系统。

1. 对比单独管理,好处在哪里?

维度 单独管理(docker run) Docker Compose
启动/停止 多个命令或复杂脚本 docker compose up/down 一键操作
启动顺序 手动 sleep 或检测 depends_on + 健康检查
网络配置 手动创建并指定 自动创建项目专属网络
服务发现 --link(已废弃)或外部 DNS 容器名自动解析为 IP
环境变量 每个容器单独设置 统一在 environment 中管理
配置复用 无法轻松切换环境 支持多 Compose 文件覆盖
卷管理 逐个创建命名卷 顶层 volumes: 统一声明
日志查看 多个终端看日志 docker compose logs -f 聚合
团队协作 每个人需记住所有参数 共享 Compose 文件即可复现

2. 容器间如何通信?

在 Compose 中,所有服务会自动加入同一个自定义桥接网络。在同一网络内,容器可以通过服务名直接访问对方。

例如,在 docker-compose.yml 中定义了服务 dbredis,那么应用代码中连接数据库时可以写 db:5432,连接缓存时写 redis:6379。Compose 内置 DNS 会自动解析服务名到对应容器的 IP。

对外暴露的服务(如 HTTP API)才需要用 ports 映射到宿主机。内部通信完全不需要映射端口。

3. 推荐的目录结构

为你的项目创建一个专属目录,所有内容都放在里面:

复制代码
my-project/
├── docker-compose.yml   # 核心配置文件
├── .env                 # 环境变量(敏感信息)
├── web/                 # Web 服务目录
│   ├── Dockerfile
│   └── ...
├── db/                  # 数据库目录
│   └── init.sql
├── cache/               # 缓存配置
│   └── redis.conf
├── data/                # 数据卷(数据库文件等)
├── logs/                # 日志卷
└── scripts/             # 辅助脚本

4. 一个实际的 Compose 示例

复制代码
version: '3.8'

networks:
  app-net:

volumes:
  db_data:
  cache_data:

services:
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: app_user
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app_user"]
    networks:
      - app-net

  cache:
    image: redis:7-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}
    volumes:
      - cache_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
    networks:
      - app-net

  web:
    build: ./web
    ports:
      - "8080:8080"
    environment:
      DB_HOST: db
      REDIS_HOST: cache
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_healthy
    networks:
      - app-net

启动命令:docker compose up -d

停止并清理:docker compose down


三、逐步添加服务:渐进式集成

在开发过程中,完全可以在 Compose 项目中逐步增加服务模块

例如,先只配置数据库并运行起来,等它稳定后,再编辑 docker-compose.yml 添加缓存服务,然后执行 docker compose up -d。Compose 只会启动新添加的服务,已经运行的老服务不受影响。

注意事项

1)新服务会自动加入同一个网络,可以用服务名访问已有服务。

2)如果两个服务需要映射到宿主机的同一个端口(例如都映射 8080),需要错开(一个映射 8080,另一个映射 8081),或者只让其中一个对外暴露。

3)如果修改了已有服务的配置(如环境变量),再次 up -d 会导致该服务重启,可能造成短暂中断。

逐步添加的方式非常适合迭代开发和调试。待所有服务稳定后,再把完整的 Compose 文件提交到版本库。


四、镜像是全局的:拉取一次,到处复用

很多人会有疑问:拉取的镜像存在哪里?能不能在多个项目中共用?

答案是:Docker 镜像是机器级别的全局资源 ,存储于 /var/lib/docker(Linux)。通过 docker pull 拉取一次镜像后,同一台机器上的任何 Compose 项目或 docker run 命令都可以直接使用,无需重复下载。

例如,拉取了 postgres:15,那么 project-a 可以用它,project-b 也可以直接用。Docker 的联合文件系统还会让多个基于相同基础镜像的自定义镜像共享底层,节省磁盘空间。

预拉取镜像的好处

1)加速首次 docker compose up(无需等待下载)

2)支持离线或弱网环境部署

3)锁定版本,避免意外拉取到最新镜像

可以先执行:

复制代码
docker pull postgres:15-alpine
docker pull redis:7-alpine
docker pull node:18-alpine

然后再编写 docker-compose.yml 并启动。Compose 会直接使用本地镜像。


五、Docker Compose 与 Docker Swarm:分工协作,不是二选一

很多初学者会混淆 Compose 和 Swarm,认为它们是对立的。实际上,它们是 Docker 生态中定位不同、又能无缝协作的两个工具。

特性 Docker Compose Docker Swarm
核心目标 单机开发、测试环境编排 生产环境多主机集群管理
部署范围 单台 Docker 主机 多台 Docker 主机组成的集群
高可用 不支持 支持,节点故障自动恢复
负载均衡 需自行配置 内置服务发现和负载均衡
弹性伸缩 手动 scale 内置,支持按需伸缩
滚动更新 手动操作 内置,零宕机更新
学习曲线 较低(原生 Docker 命令)

典型工作流

开发阶段用 Compose :在本地写好 docker-compose.yml,一条命令跑起整个系统。

生产阶段用 Swarm :将同一份 Compose 文件(需版本 3 以上)通过 docker stack deploy 部署到 Swarm 集群,自动享受高可用、负载均衡、滚动更新等能力。

也就是说,Compose 负责定义,Swarm 负责规模化运行。可以从 Compose 开始,等需要集群能力时平滑迁移到 Swarm。


六、总结与最佳实践

1. 用 Compose 管理多服务项目:无论你是微服务还是传统 Web 应用,Compose 都能极大降低复杂度。

2. 使用自定义网络和容器名通信:避免硬编码 IP,利用内置 DNS。

3. 合理规划目录结构:每个服务独立目录,数据卷和日志卷分开存放。

4. 先拉取镜像再写 Compose:提速、锁定版本、支持离线。

5. 利用健康检查和 depends_on:控制启动顺序,确保依赖就绪。

6. 环境变量与 .env 文件:敏感信息不入 Compose 文件,用变量替代。

7. 开发迭代时逐步添加服务:不影响已运行的服务。

8. 生产环境考虑 Swarm 或 K8s:根据规模选择合适的编排工具。

Docker 已经成为云原生时代的基石。掌握它,不仅能高效管理复杂的多服务系统,更能为后续学习 Kubernetes、服务网格等高级技术打下坚实基础。

相关推荐
w6100104668 小时前
CKAD-2026-金丝雀部署
linux·运维·服务器·k8s
.小小陈.8 小时前
深度拆解 Linux Ext 系列文件系统:从硬件底层到软硬链接全流程
linux·运维·服务器
Geoking.8 小时前
GitHub 多账号生存指南:从 SSH 连接到 GPG 签名全流程
运维·ssh·github
分布式存储与RustFS8 小时前
Windows原生版RustFS:无需Docker,1分钟本地对象存储环境搭建
windows·docker·容器·对象存储·minio·企业存储·rustfs
问道飞鱼8 小时前
【分布式技术】RustFS 非 Docker 部署完整指南:从单机到生产集群
分布式·docker·容器·rustfs
Frank_refuel8 小时前
Linux操作系统 - > 进程信号(中)
linux·运维·服务器
阿杜杜不是阿木木8 小时前
authentik开源身份认证与管理平台-与 Jenkins 集成(5)
运维·servlet·jenkins·authing·authentik
minji...9 小时前
Linux 多线程(二)进程虚拟地址空间&&页表&&物理地址
linux·运维·服务器
liqianpin19 小时前
Nginx WebSocket 长连接及数据容量配置
运维·websocket·nginx