7.1 挂载卷
在 Docker Compose 中挂载卷和网络可以创建灵活高效的多容器应用。卷(volumes)用于存储需要保留在容器外的数据,而网络(networks)提供容器之间的交互。在这节课里,我们将详细讲解如何在 Docker Compose 中使用卷和网络。
Docker 中的卷允许将数据保存在容器外,即使容器停止或删除后仍然可以获取这些数据。这对于存储数据库数据、日志文件和其他需要长期保存的数据特别有用。
卷的类型:
- 命名卷 (Named Volumes): 由 Docker 管理,并存储在宿主机的特定目录中。
- 绑定卷 (Bind Mounts): 从宿主机指定的目录挂载到容器中。
在 Docker Compose 中定义卷
命名卷的示例
在这个例子中,创建了一个命名卷 postgres-data
,它被挂载到容器 db
中的目录 /var/lib/postgresql/data
。
Yaml
version: '3.8'
services:
db:
image: postgres:latest
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:
绑定卷的示例
在这个例子中,本地目录和文件 nginx.conf
和 html
被作为绑定卷挂载到容器 web
中。
Yaml
version: '3.8'
services:
web:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
7.2 网络挂载
Docker Compose中的网络允许容器彼此交互。每个容器可以连接到一个或多个网络,从而实现隔离和流量管理。
网络类型:
- 桥接网络(Bridge): 默认情况下,容器连接到桥接网络,这允许它们在同一主机上交互。
- 覆盖网络(Overlay): 用于在Docker Swarm集群中,不同主机运行的容器之间的交互。
- 网络插件(Network Plugins): 允许使用第三方网络驱动以实现更复杂的配置。
创建和使用自定义网络的示例
在这个示例中,创建了两个自定义网络front-end和back-end。服务app连接到两个网络,服务web仅连接到front-end,服务db仅连接到back-end。
Yaml
version: '3.8'
services:
web:
image: nginx:latest
networks:
- front-end
app:
image: myapp:latest
networks:
- front-end
- back-end
db:
image: postgres:latest
networks:
- back-end
networks:
front-end:
back-end:
实用建议:
- 使用命名卷: 命名卷由Docker管理,简单易用,方便数据管理。命名卷可以同时连接到多个服务。例如,后端服务记录日志,而监控服务分析日志并在检测到
error
级别错误时通知。 - 网络隔离: 使用多个网络可以隔离应用程序的不同部分并控制它们的交互。
- 存储配置文件: 使用绑定卷挂载配置文件,这样可以在无需重新构建镜像的情况下轻松更改配置。
- 网络安全: 限制网络访问,使只有必要的容器可以交互,从而提高应用程序的安全性。
7.3 使用卷和网络的示例
以下是在 Docker Compose 中使用卷和网络的示例:
示例 1: 具有 Web 服务器和数据库的应用
Yaml
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./html:/usr/share/nginx/html
networks:
- webnet
db:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- db-data:/var/lib/postgresql/data
networks:
- webnet
volumes:
db-data:
networks:
webnet:
在这个示例中:
- Web 服务器 nginx 和数据库 PostgreSQL 都连接到同一网络 webnet,这使它们能够相互通信。如果只有一个网络,可以不指定——会自动创建默认网络。
- 数据库的数据保存在命名卷 db-data 中,这确保了在容器重启时数据不会丢失。
示例 2: 多层应用
Yaml
version: '3.8'
services:
frontend:
image: myfrontend:latest
networks:
- front-tier
- back-tier
backend:
image: mybackend:latest
networks:
- back-tier
volumes:
- backend-data:/var/lib/backend
database:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: example
volumes:
- db-data:/var/lib/mysql
networks:
- back-tier
volumes:
backend-data:
db-data:
networks:
front-tier:
back-tier:
在这个示例中:
- 创建了两个网络:front-tier 和 back-tier。
- 服务 frontend 连接到两个网络,这使它能够与 backend 和外部客户端通信。
- 服务 backend 和 database 仅连接到 back-tier 网络,以确保它们的隔离和通信。
- 服务 backend 和 database 的数据分别保存在单独的命名卷 backend-data 和 db-data 中。
GO TO FULL VERSION