3、Composition文件结构:顶层字段解析
好,咱们今天来聊聊Compose文件的结构。说白了,它就是一份「服务部署说明书」。你写清楚了,Docker就能按你的意思把整个应用跑起来。
我个人习惯把Compose文件看作一个「三层结构」:顶层声明、服务定义、以及底层资源。今天咱们就聚焦顶层——那些写在最前面的字段。
3.1 版本声明:别小看这一行
每个Compose文件的第一行,通常是版本声明。比如:
version: '3.8'
嗯,这里要注意。版本号决定了你能用哪些功能。我见过不少新手直接写version: '3',结果某些字段不生效,排查半天才发现是版本太老。
| 版本 | 关键特性 | 我的建议 |
|---|---|---|
| 2.x | 基础功能,不支持Swarm | 别用了,太老 |
| 3.x | 支持Swarm、secrets、configs | 推荐3.8+ |
| 3.8+ | 支持GPU、扩展字段 | 当前首选 |
version: '3.8' 基本不会错。我目前在用的项目都统一用这个版本。
3.2 services:核心中的核心
services 是Compose文件的灵魂。你想想看,整个文件就是为了定义「要跑哪些服务」。
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
每个服务就是一个容器。你可以定义它的镜像、端口、环境变量、挂载卷等等。我曾经在项目中遇到一个问题:两个服务用了同一个端口,结果启动时冲突了。排查了半天才发现是端口映射写重复了。
[a-z0-9_-]。
3.3 networks:让服务能互相通信
默认情况下,Compose会创建一个默认网络,所有服务都在里面。但有时候你需要隔离网络,或者指定IP段。
networks:
frontend:
driver: bridge
backend:
driver: overlay
ipam:
config:
- subnet: 10.0.1.0/24
我个人习惯把前端服务和后端服务放在不同网络里。前端只能访问后端暴露的端口,后端不能直接访问前端。这样安全性会好很多。
项目名_default 的网络。但显式声明会让你的配置更清晰。
3.4 volumes:数据持久化的命根子
容器一重启,数据就丢了?那肯定不行。volumes就是用来解决这个问题的。
volumes:
db_data:
driver: local
logs:
driver: local
driver_opts:
type: none
device: /var/log/myapp
o: bind
记得有一次,我部署了一个数据库服务,没挂载卷。结果容器崩溃重启后,所有数据都没了。嗯,从那以后我再也不敢不挂载卷了。
3.5 configs:配置管理的优雅方案
configs是Swarm模式下才有的功能。它允许你把配置文件独立出来,不用塞进镜像里。
configs:
my_config:
file: ./config/nginx.conf
app_config:
external: true
你想想看,如果每次改配置都要重新构建镜像,那得多麻烦。用configs,配置文件可以单独管理,热更新也方便。
/configs/ 目录下。你可以通过 target 字段指定挂载路径。
3.6 secrets:敏感信息的安全港湾
密码、API密钥、证书……这些敏感信息不能明文写在Compose文件里。secrets就是干这个的。
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
external: true
name: my_api_key_v1
我曾经见过有人直接把数据库密码写在环境变量里,结果代码泄露后整个数据库被拖库。用secrets,至少能保证敏感信息不会出现在日志或版本控制里。
.env 文件替代,但安全性会差一些。
3.7 命名规范:好名字省一半调试时间
命名这事,看似简单,其实坑不少。我总结了几条经验:
- 服务名:全小写,用连字符分隔。比如
web-api、db-master - 网络名:用有意义的名称,比如
frontend-net、backend-net - 卷名:加上用途前缀,比如
db-data、app-logs - 配置名:包含版本号,比如
nginx-config-v2
说白了,命名规范就是让你三个月后回来看代码,还能一眼看懂每个资源是干嘛的。
3.8 知识结构图
下面这张图,帮你理清Compose文件顶层字段的关系:
这张图把顶层字段的关系梳理得很清楚。services是核心,其他字段都是为它服务的。networks、volumes、configs、secrets各自负责不同的资源类型,但它们之间可以互相引用。
公众号:蓝海资料掘金营,微信deep3321