Docker Compose从入门到实战:配置与命令全指南
一、核心概念
- Docker Compose:一个用于定义和运行多容器 Docker 应用程序的工具。
docker-compose.yml
:一个 YAML 格式的配置文件,用于配置应用程序的服务、网络和数据卷。- 服务 (Service):代表一个容器的配置,包括镜像、端口、环境变量等。一个
docker-compose.yml
可以定义多个服务(如一个 Web 服务,一个数据库服务)。 - 项目 (Project):由一组关联的服务组成,默认使用当前目录名作为项目名。可以通过
-p
选项指定。
二、基本文件结构
一个最简单的 docker-compose.yml
文件包含以下部分:
version: '3.8' # 指定 Compose 文件格式的版本services: # 定义所有服务的核心部分service1: # 第一个服务...配置...service2: # 第二个服务...配置...networks: # (可选)定义自定义网络my-net:volumes: # (可选)定义数据卷my-data:
三、常用服务配置项详解
1. 镜像与构建
配置项 | 说明 | 示例 |
---|---|---|
image | 直接从仓库拉取镜像 | image: nginx:latest |
build | 根据 Dockerfile 构建镜像 | build: . 或 build: ./dir |
context | (在 build 下) 构建上下文路径 | build: { context: . } |
dockerfile | (在 build 下) 指定 Dockerfile 文件名 | build: { context: ., dockerfile: Dockerfile.dev } |
示例:
services:webapp:build: . # 使用当前目录下的 Dockerfile 构建镜像# 等同于:# build:# context: .# dockerfile: Dockerfiledb:image: postgres:13 # 使用现成的镜像
2. 端口映射
配置项 | 说明 | 示例 |
---|---|---|
ports | 映射端口 [主机端口]:[容器端口] | ports: - "8080:80" |
随机映射主机端口 | ports: - "3000" (容器3000端口随机映射到主机) |
示例:
services:nginx:image: nginxports:- "80:80" # 主机80端口 -> 容器80端口- "443:443" # 主机443端口 -> 容器443端口api:image: my-apiports:- "3000" # 容器3000端口随机映射到主机某端口
3. 环境变量
配置项 | 说明 | 示例 |
---|---|---|
environment | 直接以 key-value 形式设置 | environment: MY_VAR: value |
env_file | 从文件加载环境变量 | env_file: - ./.env |
示例:
services:db:image: postgres:13environment:POSTGRES_DB: mydbPOSTGRES_USER: userPOSTGRES_PASSWORD: password# 或者使用 env_fileenv_file:- ./db.env # 文件内容:POSTGRES_PASSWORD=secret
4. 数据卷与挂载
配置项 | 说明 | 示例 |
---|---|---|
volumes | 挂载宿主机目录或命名的数据卷 | volumes: - /host/path:/container/path |
使用匿名卷 | volumes: - /container/data | |
使用命名的数据卷 | volumes: - named-volume:/app/data |
示例:
services:web:image: nginxvolumes:- ./html:/usr/share/nginx/html # 挂载主机目录(常用於代码开发)- nginx-logs:/var/log/nginx # 使用命名的数据卷持久化日志# 在文件底部定义命名的数据卷
volumes:nginx-logs: # 声明一个名为 nginx-logs 的数据卷,Docker 会自动创建它
5. 依赖与启动顺序
配置项 | 说明 | 示例 |
---|---|---|
depends_on | 指定服务依赖关系,控制启动顺序 | depends_on: - db |
healthcheck | 定义健康检查,depends_on 可等待服务健康 | 见下方示例 |
示例:
services:webapp:build: .depends_on:- db # 确保 db 服务先启动- redis# 更佳实践:使用健康检查确保依赖服务真正可用# depends_on:# db:# condition: service_healthy# redis:# condition: service_starteddb:image: postgres:13healthcheck: # 为 db 服务定义健康检查test: ["CMD-SHELL", "pg_isready -U postgres"]interval: 10stimeout: 5sretries: 5
6. 网络
配置项 | 说明 | 示例 |
---|---|---|
networks | 将服务连接到自定义网络 | networks: - my-frontend |
ports | 暴露端口到宿主机 | ports: - "80:80" |
示例:
services:proxy:image: nginxnetworks:- frontendapp:build: .networks:- frontend- backenddb:image: postgresnetworks:- backend# 在文件底部定义网络
networks:frontend:backend:
四、完整实战示例:WordPress + MySQL
这是一个经典的多服务应用示例。
version: '3.8'services:db:image: mysql:8.0volumes:- db_data:/var/lib/mysql # 使用数据卷持久化数据库restart: alwaysenvironment:MYSQL_ROOT_PASSWORD: some_root_passwordMYSQL_DATABASE: wordpressMYSQL_USER: wordpressMYSQL_PASSWORD: wordpress_passwordnetworks:- wordpress-nethealthcheck: # 健康检查,确保数据库完全启动test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-p$$MYSQL_ROOT_PASSWORD"]interval: 10stimeout: 5sretries: 5wordpress:depends_on:db:condition: service_healthy # 等待数据库健康后再启动image: wordpress:latestports:- "8000:80" # 将主机的8000端口映射到容器的80端口restart: alwaysenvironment:WORDPRESS_DB_HOST: db:3306 # 使用服务名“db”作为主机名(Docker DNS)WORDPRESS_DB_USER: wordpressWORDPRESS_DB_PASSWORD: wordpress_passwordWORDPRESS_DB_NAME: wordpressvolumes:- ./wp-content:/var/www/html/wp-content # 挂载主题和插件目录方便开发networks:- wordpress-netvolumes:db_data: # 声明一个命名卷用于数据库持久化networks:wordpress-net: # 声明一个自定义网络,让两个容器可以互通
五、常用命令
编写好 docker-compose.yml
后,使用以下命令操作:
命令 | 说明 |
---|---|
docker-compose up | 创建并启动所有服务(前台) |
docker-compose up -d | 创建并在后台启动所有服务(最常用) |
docker-compose down | 停止并删除所有容器、网络(最常用) |
docker-compose down -v | down 的同时删除数据卷(慎用!) |
docker-compose ps | 列出本项目中的所有容器 |
docker-compose logs | 查看所有服务的日志 |
docker-compose logs -f service_name | 实时追踪特定服务的日志 |
docker-compose exec service_name command | 在服务的容器中执行命令 |
docker-compose build | 重新构建服务的镜像 |
docker-compose restart | 重启所有服务 |
docker-compose pull | 拉取服务的最新镜像 |
最佳实践
- 使用
.env
文件:将敏感信息(密码、密钥)和可能变化的配置(端口号)放在.env
文件中,并在docker-compose.yml
中引用:${VARIABLE_NAME}
。 - 指定版本:始终在文件顶部使用
version
键,并选择与你的 Docker Engine 兼容的版本。 - 使用自定义网络:让 Compose 为你管理网络,服务间可以使用服务名作为主机名互相访问(Docker 内置 DNS)。
- 合理使用数据卷:对需要持久化的数据(数据库、日志)使用命名卷或绑定挂载。
- 定义健康检查:确保服务间的依赖是真正可用的,而不仅仅是容器启动了。