网站Logo 开飞机的舒克

Docker Compose

dddd
9
2026-01-20

Docker Compose 学习指南

1. 什么是 Docker Compose

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

核心优势

  • 简化配置:使用 YAML 文件统一管理所有服务配置

  • 一键部署:单命令启动/停止所有服务

  • 环境一致性:确保开发、测试和生产环境的一致性

  • 服务编排:轻松管理服务间的依赖关系

  • 扩展性强:支持水平扩展服务

2. 安装 Docker Compose

Windows 环境

对于 Windows 用户,Docker Compose 通常随 Docker Desktop 一起安装。如果您已经安装了 Docker Desktop,则无需单独安装 Compose。

验证安装

打开命令提示符或 PowerShell,运行以下命令验证 Docker Compose 是否已安装:

docker-compose --version

如果显示版本信息,则说明安装成功。

3. Docker Compose 核心概念

3.1 服务 (Services)

服务是 Compose 配置的核心,代表一个要运行的容器。每个服务可以指定:

  • 镜像名称

  • 端口映射

  • 环境变量

  • 卷挂载

  • 依赖关系

  • 重启策略

3.2 网络 (Networks)

网络用于连接不同的服务,使它们可以相互通信。Compose 会自动创建默认网络,也可以自定义网络。

3.3 卷 (Volumes)

卷用于持久化数据,或在服务间共享数据。支持多种卷类型:

  • 命名卷

  • 匿名卷

  • 绑定挂载(主机目录映射)

4. docker-compose.yml 配置文件详解

4.1 基本结构

version: "3.8" # Compose 文件版本
services: # 服务定义
  web: # 服务名称
    image: nginx # 使用的镜像
    ports: # 端口映射
      - "80:80"
    networks: # 网络配置
      - my-network
    volumes: # 卷挂载
      - ./html:/usr/share/nginx/html
  db:
    image: mysql
    environment: # 环境变量
      - MYSQL_ROOT_PASSWORD=secret
    volumes:
      - db-data:/var/lib/mysql

networks: # 网络定义
  my-network:
    driver: bridge

volumes: # 卷定义
  db-data:

4.2 常用配置项

4.2.1 服务配置

配置项

说明

示例

image

指定服务使用的镜像

image: nginx:latest

build

从 Dockerfile 构建镜像

build: ./web

ports

端口映射 (主机:容器)

ports: ["80:80", "443:443"]

environment

设置环境变量

environment: ["MYSQL_ROOT_PASSWORD=secret"]

volumes

卷挂载

volumes: ["db-data:/var/lib/mysql"]

depends_on

服务依赖关系

depends_on: [db]

restart

重启策略

restart: always

networks

加入的网络

networks: [my-network]

command

覆盖容器默认命令

command: ["npm", "start"]

working_dir

设置工作目录

working_dir: /app

user

指定运行用户

user: "1000:1000"

4.2.2 网络配置

配置项

说明

示例

driver

网络驱动

driver: bridge

ipam

IP 地址管理

ipam: { config: [{ subnet: "172.20.0.0/16" }] }

external

使用外部网络

external: true

4.2.3 卷配置

配置项

说明

示例

driver

卷驱动

driver: local

driver_opts

驱动选项

driver_opts: { type: "nfs", o: "addr=192.168.1.1,rw", device: ":/path" }

external

使用外部卷

external: true

5. 常用 Docker Compose 命令

5.1 基本命令

命令

说明

示例

docker-compose up

启动所有服务

docker-compose up -d(后台运行)

docker-compose down

停止并移除所有服务、网络和卷

docker-compose down --volumes

docker-compose ps

查看所有服务状态

docker-compose ps

docker-compose logs

查看服务日志

docker-compose logs -f(实时跟踪)

docker-compose build

构建服务镜像

docker-compose build --no-cache

docker-compose restart

重启服务

docker-compose restart web

docker-compose stop

停止服务

docker-compose stop web

docker-compose start

启动服务

docker-compose start web

docker-compose rm

删除停止的服务

docker-compose rm -v

5.2 高级命令

命令

说明

示例

docker-compose exec

进入正在运行的容器

docker-compose exec web bash

docker-compose scale

扩展服务实例数

docker-compose scale web=3

docker-compose top

查看服务进程

docker-compose top

docker-compose config

验证配置文件

docker-compose config -q(静默模式)

6. 实际案例:多服务应用部署

6.1 案例:Node.js + MongoDB 应用

创建一个简单的 Node.js Web 应用,使用 MongoDB 作为数据库。

6.1.1 项目结构

node-mongo-app/
├── docker-compose.yml
├── web/
│   ├── Dockerfile
│   ├── package.json
│   └── app.js
└── .env

6.1.2 web/Dockerfile

FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

6.1.3 web/package.json

{
  "name": "node-mongo-app",
  "version": "1.0.0",
  "description": "A simple Node.js + MongoDB app",
  "main": "app.js",
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.3"
  }
}

6.1.4 web/app.js

const express = require("express");
const mongoose = require("mongoose");
const app = express();
const PORT = process.env.PORT || 3000;
const MONGODB_URI = process.env.MONGODB_URI || "mongodb://mongo:27017/mydb";

// Connect to MongoDB
mongoose
  .connect(MONGODB_URI)
  .then(() => console.log("MongoDB connected"))
  .catch((err) => console.error("MongoDB connection error:", err));

// Define a schema
const ItemSchema = new mongoose.Schema({
  name: String,
  description: String,
});

const Item = mongoose.model("Item", ItemSchema);

// Routes
app.get("/", async (req, res) => {
  res.send("Hello from Node.js + MongoDB app!");
});

app.get("/items", async (req, res) => {
  const items = await Item.find();
  res.json(items);
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

6.1.5 docker-compose.yml

version: "3.8"

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - MONGODB_URI=mongodb://mongo:27017/mydb
    depends_on:
      - mongo
    volumes:
      - ./web:/app
      - /app/node_modules # 避免覆盖容器内的 node_modules
    restart: unless-stopped

  mongo:
    image: mongo:5.0
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
    restart: unless-stopped

volumes:
  mongo-data:
    driver: local

6.1.6 .env

NODE_ENV=development
PORT=3000

6.1.7 启动服务

# 进入项目目录
cd node-mongo-app

# 启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

7. 最佳实践

7.1 配置文件管理

  • 使用 .env 文件管理敏感信息和环境变量

  • 为不同环境创建不同的配置文件,如 docker-compose.prod.yml

  • 使用 extends 关键字复用配置

7.2 性能优化

  • 使用轻量级镜像(如 Alpine 版本)

  • 合理设置资源限制(cpu_shares, mem_limit

  • 避免不必要的端口映射

7.3 安全建议

  • 避免在配置文件中硬编码密码和敏感信息

  • 使用私有镜像仓库

  • 定期更新镜像版本

  • 限制容器的权限(使用非 root 用户运行)

7.4 开发工作流

  • 使用绑定挂载进行开发,实时同步代码变更

  • 分离开发和生产环境配置

  • 使用 CI/CD 流水线自动化部署

8. 常见问题与解决方案

8.1 服务启动顺序问题

问题:依赖服务未准备好,导致服务启动失败

解决方案

  • 使用 depends_on 配置服务依赖

  • 使用健康检查(healthcheck)确保服务就绪

  • 实现服务启动重试机制

services:
  web:
    depends_on:
      db:
        condition: service_healthy
  db:
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

8.2 卷数据持久化

问题:容器删除后数据丢失

解决方案

  • 使用命名卷而非匿名卷

  • 定期备份卷数据

# 备份卷数据
docker run --rm -v db-data:/data -v $(pwd):/backup alpine tar czf /backup/db-backup.tar.gz /data

# 恢复卷数据
docker run --rm -v db-data:/data -v $(pwd):/backup alpine tar xzf /backup/db-backup.tar.gz -C /

8.3 网络连接问题

问题:服务间无法通信

解决方案

  • 确保服务在同一网络中

  • 使用服务名称作为主机名进行通信

  • 检查防火墙设置

9. 总结

Docker Compose 是一个强大的工具,可以简化多容器应用的部署和管理。 希望本文对您学习 Docker Compose 有所帮助!祝您容器化之旅愉快!