Docker Compose 单机多服务开发:5 个真会踩到的细节
做本地多服务开发时,docker compose up 往往第一次报错、第二次才跑起来。这篇记录几个反复遇到的配置细节,都不需要改业务代码。
一、.dockerignore 里的裸文件名只匹配构建上下文根目录
很多人习惯在 .dockerignore 里写一行 .env,以为能忽略所有子目录下的 .env。实际上这条规则只匹配构建上下文根目录下的 .env,像 service-a/.env 这种不会被忽略,仍然会被打进镜像。正确写法是 **/.env。
排查方法:构建完用 docker run --rm <image> ls -a / 看一眼产物,比对着规则猜要快。
二、healthcheck 配合 depends_on 的条件,才能真等到依赖就绪
depends_on 默认只等容器"启动",不等服务"可用"。数据库容器几百毫秒就起来了,但真正能接受连接往往要十几秒,于是应用第一次启动必然连接失败。
两种做法:一是给依赖服务加 healthcheck,并在应用服务里写 depends_on 的 condition: service_healthy;二是在应用启动脚本里做重试。推荐第一种,语义清晰。注意 healthcheck 的 start_period 要给够,否则初始阶段的重试会被算成失败次数,容器直接被标记 unhealthy。
三、日志不设上限,磁盘迟早被吃掉
默认 json-file 驱动的日志会一直增长。长期跑的开发机或单机部署,建议在 compose 里统一加上上限:logging 用 json-file 驱动,options 里设 max-size 为 20m、max-file 为 3。出问题时日志往往是最容易撑爆磁盘的东西。
四、端口冲突要先查再改
报 bind: address already in use 时,先确认是谁占着端口:Linux/macOS 用 ss -tlnp | grep 5173;Windows 用 netstat -ano | findstr 5173 找到 PID,再 tasklist /FI "PID eq 那个PID"。
确认之后再改 compose 的端口映射。不要凭感觉乱换端口——换完之后前端里写死的后端地址往往没跟着改,问题会从"起不来"变成"起来了但接口 404",更难查。
五、.env 只影响 compose 插值,不影响容器里的进程
.env 里的变量默认只用于 compose 文件里的 ${VAR} 插值,不会被自动注入到容器的环境变量里。想让容器里的进程读到,要么在服务的 environment 段显式声明,要么用 env_file。构建阶段更特殊,Dockerfile 里的 RUN 拿不到运行时环境变量,需要 ARG 才能传进去。
分不清这两层,就会出现"宿主机上 echo 有值、进容器 printenv 是空"的经典现象。
小结
这几个点单独看都不复杂,但都发生在"配置看起来正确、行为却不符合直觉"的位置,排查时很容易先去怀疑代码。养成三个习惯基本能绕开:构建产物看一眼、依赖用健康检查、日志和端口都设上限并确认来源。
- 点赞
- 收藏
- 关注作者
评论(0)