一、Docker“顺序”理解
1、代码片段如下
...
ctra-tenant-admin-api:
image: registry.cn-beijing.aliyuncs.com/xxx/ctragorace-go-admin-api-new
container_name: ctra-tenant-admin-api
restart: always
volumes:
- /home/ctra/ctra-core-tenant/admin/ctra_go_admin.yaml:/app/etc/ctra_go_admin.yaml
# - /home/ctra/yaml-all/logs/admin:/home/data/logs/CtraGoAdmin/api
ports:
- '1108:4007'
networks:
simple-admin:
aliases:
- ctra-tenant-admin-api
deploy:
resources:
limits:
cpus: '0.5'
memory: 500M
reservations:
cpus: '0.05'
memory: 200M
ctra-tenant-admin-webapp:
image: registry.cn-beijing.aliyuncs.com/xxx/ctra-web-ui
container_name: ctra-tenant-admin-webapp
restart: always
ports:
- '1088:80'
networks:
simple-admin:
aliases:
- ctra-tenant-admin-webapp
depends_on:
- ctra-tenant-admin-api
deploy:
resources:
limits:
cpus: '0.5'
memory: 500M
reservations:
cpus: '0.05'
memory: 200M
...
2、depends_on
在 docker-compose 配置中,depends_on 的作用是声明服务间的依赖关系
也就是说:当前服务启动时,应该先启动哪些其他服务。
✅ 在你的配置中:
depends_on:
- ctra-tenant-admin-api
意思是:
- 当前服务 ctra-tenant-admin-webapp 在启动前 会先启动 ctra-tenant-admin-api 容器;
- 它保证 容器启动顺序,但不保证 API 服务已就绪(例如端口真的能连上)。
3、错误使用方式
⚠️ 常见误解:depends_on ≠ 服务可用!
services:
app:
depends_on:
- db
db:
image: postgres
即使 db 容器先启动,PostgreSQL 服务可能还没准备好(还在初始化),此时 app 就连不上数据库了!
4、最价实践
✅ 更可靠的方式(推荐)
若你希望确保依赖服务“就绪”再启动,可以使用 健康检查(healthcheck)+ 重试机制 或第三方脚本控制启动,例如:
services:
ctra-tenant-admin-api:
image: your-api-image
healthcheck:
test: curl --fail http://localhost:8080/health || exit 1
interval: 10s
timeout: 3s
retries: 5
ctra-tenant-admin-webapp:
depends_on:
ctra-tenant-admin-api:
condition: service_healthy
🧠 注意:condition: service_healthy 仅在 Docker Compose v3.4+ 且使用 docker-compose CLI(非 swarm 模式)时可用。
5、总结
✅ 总结:你的配置中 depends_on 是什么意思?
项目 | 含义 |
---|---|
depends_on | 控制启动顺序,先启动ctra-tenant-admin-api,在启动 ctra-tenant-admin-webapp |
不做的事 | 不会检查API是否“就绪”或“健康” |
建议 | 配合 healthcheck 使用,或在入口脚本中加重试逻辑 |
二、完整方案
✅ 一套完整方案:容器启动脚本 + depends_on + 健康检查
1、添加 wait-for-api.sh 脚本
在你的前端容器 ctra-tenant-admin-webapp 中,添加一个等待脚本:
🔧 文件:wait-for-api.sh
#!/bin/sh
HOST=${API_HOST:-ctra-tenant-admin-api}
PORT=${API_PORT:-8080}
echo "Waiting for API at $HOST:$PORT..."
while ! nc -z $HOST $PORT; do
sleep 1
done
echo "API is up - launching webapp..."
exec "$@"
✅ 说明:
- 默认等待名为 ctra-tenant-admin-api 的服务 8080 端口(可通过环境变量修改)
- nc -z 会检查端口是否开放
- “exec “$@”” 会将控制权转交给后续启动命令
2、修改 docker-compose.yml
services:
ctra-tenant-admin-webapp:
image: registry.cn-beijing.aliyuncs.com/xxx/ctra-web-ui
container_name: ctra-tenant-admin-webapp
restart: always
ports:
- '1088:80'
networks:
simple-admin:
aliases:
- ctra-tenant-admin-webapp
depends_on:
- ctra-tenant-admin-api
volumes:
- ./wait-for-api.sh:/wait-for-api.sh
entrypoint: [ "sh", "/wait-for-api.sh" ]
environment:
API_HOST: ctra-tenant-admin-api
API_PORT: 8080
deploy:
resources:
limits:
cpus: '0.5'
memory: 500M
reservations:
cpus: '0.05'
memory: 200M
3、给脚本加执行权限(如果在 Linux)
chmod +x wait-for-api.sh
4、最终效果
当你执行 docker-compose up 时:
1. ctra-tenant-admin-api 容器先启动;
2. ctra-tenant-admin-webapp 启动时,先执行 /wait-for-api.sh,循环检测 API 的端口是否可连接;
3. 直到端口开放,再启动 Web 容器的主服务(通常是 nginx 或 node)。