长安的Docker教程长安的Docker教程
首页
快速开始
编程指南
首页
快速开始
编程指南
  • 🎯 Docker入门篇

    • 快速开始
    • Docker是什么?
    • 为什么要用Docker?
    • 安装Docker
    • 第一个容器
  • 📦 Docker基础篇

    • Docker镜像详解
    • 容器操作详解
    • 编写Dockerfile
    • 数据卷(Volumes)
    • Docker网络
  • ⚡ Docker进阶篇

    • Docker Compose
    • 多阶段构建
    • Docker性能优化
    • Docker最佳实践
  • 🚀 实战项目

    • 实战:部署Node.js应用
    • 实战:搭建数据库环境
    • 实战:微服务架构
  • 💡 常见问题

    • 常见问题排查
    • 实用技巧

Docker Compose

嘿!长安来教你Docker Compose了!这是Docker进阶的必修课,学会了管理多容器就像玩一样简单!🚀

🤔 为什么需要Docker Compose?

痛点场景

假设你要运行一个Web应用,需要:

  • Nginx
  • Node.js应用
  • MySQL数据库
  • Redis缓存

传统方式(头疼!):

# 创建网络
docker network create my-network

# 运行MySQL
docker run -d \
  --name mysql \
  --network my-network \
  -e MYSQL_ROOT_PASSWORD=123456 \
  -e MYSQL_DATABASE=mydb \
  -v mysql-data:/var/lib/mysql \
  mysql:8.0

# 运行Redis
docker run -d \
  --name redis \
  --network my-network \
  -v redis-data:/data \
  redis:alpine

# 运行应用
docker run -d \
  --name app \
  --network my-network \
  -e DB_HOST=mysql \
  -e REDIS_HOST=redis \
  -v $(pwd):/app \
  my-app:latest

# 运行Nginx
docker run -d \
  --name nginx \
  --network my-network \
  -p 80:80 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
  nginx:alpine

# 😱 命令太长了!记不住!
# 😱 每次启动要敲这么多命令!
# 😱 顺序还不能错!

Docker Compose方式(爽!):

# 一个命令搞定所有!
docker-compose up -d

# ✨ 就这么简单!

📦 安装Docker Compose

Windows/Mac

Docker Desktop已经包含Docker Compose,不需要额外安装!

验证:

docker-compose --version
# 或
docker compose version

Linux

# 下载最新版
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

# 验证
docker-compose --version

💡 长安提示:Docker新版本推荐用docker compose(空格),不带横杠

📝 第一个docker-compose.yml

创建文件

mkdir my-app
cd my-app
touch docker-compose.yml

编写配置

version: '3.8'

services:
  # Web服务
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    
  # 数据库
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: mydb
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  mysql-data:

启动服务

# 启动(后台运行)
docker-compose up -d

# 查看状态
docker-compose ps

# 查看日志
docker-compose logs

# 停止服务
docker-compose down

就是这么简单! 🎉

📚 docker-compose.yml详解

基本结构

version: '3.8'          # Compose文件版本

services:               # 服务定义
  service1:
    ...
  service2:
    ...

networks:               # 网络定义(可选)
  network1:
    ...

volumes:                # 数据卷定义(可选)
  volume1:
    ...

services(服务)

image - 指定镜像

services:
  web:
    image: nginx:alpine           # 使用镜像
    
  app:
    image: node:18-alpine
    
  db:
    image: mysql:8.0

build - 构建镜像

services:
  app:
    build: .                      # 当前目录的Dockerfile
    
  app:
    build:
      context: ./app              # 构建上下文
      dockerfile: Dockerfile.dev  # 指定Dockerfile
      args:                       # 构建参数
        NODE_VERSION: 18

ports - 端口映射

services:
  web:
    ports:
      - "80:80"                   # 宿主机:容器
      - "443:443"
      - "8080:80"                 # 宿主机8080映射到容器80

environment - 环境变量

services:
  db:
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      
  # 或者从文件读取
  app:
    env_file:
      - .env

volumes - 数据卷

services:
  db:
    volumes:
      - mysql-data:/var/lib/mysql     # 命名数据卷
      - ./config:/etc/mysql/conf.d    # 绑定挂载
      - /var/log:/var/log:ro          # 只读挂载

volumes:
  mysql-data:                          # 定义数据卷

networks - 网络

services:
  web:
    networks:
      - frontend
      - backend
      
  db:
    networks:
      - backend

networks:
  frontend:
  backend:

depends_on - 依赖关系

services:
  app:
    depends_on:
      - db
      - redis
    
  db:
    image: mysql
    
  redis:
    image: redis

注意:depends_on只保证启动顺序,不保证服务就绪!

restart - 重启策略

services:
  web:
    restart: always              # 总是重启
    
  app:
    restart: on-failure          # 失败时重启
    
  db:
    restart: unless-stopped      # 除非手动停止

command - 覆盖默认命令

services:
  app:
    command: npm start
    
  db:
    command: --default-authentication-plugin=mysql_native_password

🎯 实战案例

案例1:完整的Web应用栈

项目结构:

my-web-app/
├── docker-compose.yml
├── app/
│   ├── Dockerfile
│   ├── package.json
│   └── src/
├── nginx/
│   └── nginx.conf
└── .env

docker-compose.yml:

version: '3.8'

services:
  # Nginx反向代理
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app
    networks:
      - frontend
    restart: unless-stopped

  # Node.js应用
  app:
    build: ./app
    environment:
      NODE_ENV: production
      DB_HOST: db
      DB_PORT: 3306
      DB_NAME: mydb
      DB_USER: user
      DB_PASSWORD: ${DB_PASSWORD}
      REDIS_HOST: redis
      REDIS_PORT: 6379
    depends_on:
      - db
      - redis
    networks:
      - frontend
      - backend
    restart: unless-stopped

  # MySQL数据库
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: mydb
      MYSQL_USER: user
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - mysql-data:/var/lib/mysql
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
    networks:
      - backend
    restart: unless-stopped

  # Redis缓存
  redis:
    image: redis:alpine
    volumes:
      - redis-data:/data
    networks:
      - backend
    restart: unless-stopped

networks:
  frontend:
  backend:

volumes:
  mysql-data:
  redis-data:

.env文件:

MYSQL_ROOT_PASSWORD=super-secret-password
DB_PASSWORD=user-password

启动:

docker-compose up -d

一个命令,整个应用栈都起来了! 🎉

案例2:开发环境

docker-compose.dev.yml:

version: '3.8'

services:
  app:
    build:
      context: ./app
      dockerfile: Dockerfile.dev
    volumes:
      - ./app:/app                # 代码热更新
      - /app/node_modules         # node_modules不挂载
    ports:
      - "3000:3000"
      - "9229:9229"               # 调试端口
    environment:
      NODE_ENV: development
    command: npm run dev

  db:
    image: mysql:8.0
    ports:
      - "3306:3306"               # 暴露端口方便调试
    environment:
      MYSQL_ROOT_PASSWORD: dev123
      MYSQL_DATABASE: dev_db

使用:

# 启动开发环境
docker-compose -f docker-compose.dev.yml up -d

# 查看应用日志
docker-compose -f docker-compose.dev.yml logs -f app

案例3:WordPress + MySQL

version: '3.8'

services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress_pass
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wordpress-data:/var/www/html
    depends_on:
      - db
    restart: always

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root_pass
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress_pass
    volumes:
      - db-data:/var/lib/mysql
    restart: always

volumes:
  wordpress-data:
  db-data:

访问:http://localhost:8080

两分钟搭建一个WordPress! 🚀

🎮 Docker Compose命令

基本命令

# 启动服务
docker-compose up                 # 前台运行
docker-compose up -d              # 后台运行

# 停止服务
docker-compose stop               # 停止(不删除容器)
docker-compose down               # 停止并删除容器
docker-compose down -v            # 停止并删除容器和数据卷

# 重启服务
docker-compose restart            # 重启所有服务
docker-compose restart app        # 重启指定服务

查看状态

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs               # 所有服务的日志
docker-compose logs -f            # 实时查看
docker-compose logs -f app        # 查看指定服务
docker-compose logs --tail=100 app  # 最后100行

执行命令

# 在运行的容器中执行命令
docker-compose exec app bash
docker-compose exec app npm install
docker-compose exec db mysql -uroot -p

# 运行一次性命令
docker-compose run app npm test
docker-compose run --rm app npm install

构建和拉取

# 构建镜像
docker-compose build
docker-compose build --no-cache app

# 拉取镜像
docker-compose pull

# 构建+启动
docker-compose up --build

扩容

# 扩容服务(运行多个实例)
docker-compose up -d --scale app=3

# 现在有3个app容器在运行!

💡 最佳实践

1. 使用.env文件

# .env
DB_PASSWORD=secret
REDIS_PASSWORD=secret
NODE_ENV=production
# docker-compose.yml
services:
  app:
    environment:
      DB_PASSWORD: ${DB_PASSWORD}
      NODE_ENV: ${NODE_ENV}

记得把.env加入.gitignore!

2. 分环境配置

# 基础配置
docker-compose.yml

# 开发环境
docker-compose.dev.yml

# 生产环境
docker-compose.prod.yml

使用:

# 开发
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

# 生产
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

3. 健康检查

services:
  app:
    image: my-app
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 40s

4. 资源限制

services:
  app:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

5. 日志管理

services:
  app:
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

🔧 高级技巧

使用模板变量

services:
  app:
    image: my-app:${APP_VERSION:-latest}
    environment:
      API_URL: ${API_URL:-http://localhost:3000}

扩展服务配置

# 基础配置
x-common: &common
  restart: unless-stopped
  networks:
    - app-network

services:
  web:
    <<: *common
    image: nginx
    
  app:
    <<: *common
    build: ./app

等待服务就绪

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

💡 小结

今天长安教你精通Docker Compose:

核心概念

  1. 作用:管理多容器应用
  2. 配置文件:docker-compose.yml
  3. 常用命令:up、down、logs、exec
  4. 最佳实践:环境变量、健康检查、资源限制

必会命令

docker-compose up -d              # 启动
docker-compose down               # 停止
docker-compose ps                 # 状态
docker-compose logs -f            # 日志
docker-compose exec <服务> bash   # 进入容器

配置要点

services:        # 定义服务
  service:
    image:       # 镜像
    build:       # 构建
    ports:       # 端口
    environment: # 环境变量
    volumes:     # 数据卷
    networks:    # 网络
    depends_on:  # 依赖
    restart:     # 重启策略

🚀 下一步

Docker Compose搞定了!想让镜像更小更快?下一章长安教你 多阶段构建!


💬 长安的Compose心得:

我第一次用Docker Compose的时候,激动得要死!

以前启动项目要敲十几行命令,现在一个docker-compose up -d就搞定了!

而且配置都写在文件里,新同事来了给他一个docker-compose.yml, 一秒钟就能跑起整个项目,不用我手把手教了😂

Docker Compose是生产力工具,必须学!

建议你把自己的项目都用Compose管理起来,真的超级方便!

有问题来 编程指南 交流!

下一章见!💪

在 GitHub 上编辑此页
Next
多阶段构建