部署一个 Python + Redis + Nginx 的服务，容器启动顺序搞错了。Redis 还没 ready，Python 服务就报 Connection refused。排查了半天，发现是 depends_on 只保证容器启动顺序，不保证服务就绪。问题现象# docker-compose.yml services: web: build: . depends_on: - redis ports: - "8000:8000" redis: image: redis:7-alpine ports: - "6379:6379" docker-compose up -d Python 服务启动后报错：redis.exceptions.ConnectionError: Error 111 connecting to localhost:6379. Connection refused. 坑在于：depends_on 只保证 Redis 容器先启动，不保证 Redis 服务已经就绪。Redis 容器启动了，但 Redis 服务可能还在初始化。解决方案方案一：healthcheck + condition（推荐）services: web: build: . depends_on: redis: condition: service_healthy ports: - "8000:8000" redis: image: redis:7-alpine ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 healthcheck 定义健康检查命令，condition: service_healthy 等待 Redis 健康后再启动 web。方案二：启动脚本等待# app.py import redis import time def wait_for_redis(host, port, max_retries=30): """等待 Redis 就绪""" for i in range(max_retries): try: r = redis.Redis(host=host, port=port) r.ping() print("Redis 已就绪") return r except redis.ConnectionError: print(f"等待 Redis... ({i+1}/{max_retries})") time.sleep(1) raise Exception("Redis 连接超时") r = wait_for_redis("redis", 6379) 坑在于：这个方案需要在应用代码里加等待逻辑，不够优雅。方案三：wait-for-it 脚本services: web: build: . depends_on: - redis command: > sh -c "wait-for-it -t 30 redis:6379 -- python app.py" ports: - "8000:8000" # Dockerfile FROM python:3.11-slim # 安装 wait-for-it RUN apt-get update && apt-get install -y wait-for-it && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . 这个方案需要在镜像里安装 wait-for-it，增加镜像体积。完整配置示例Python + Redis + Nginxservices: web: build: . depends_on: redis: condition: service_healthy environment: - REDIS_HOST=redis - REDIS_PORT=6379 ports: - "8000:8000" redis: image: redis:7-alpine ports: - "6379:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 volumes: - redis_data:/data nginx: image: nginx:alpine ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: web: condition: service_started volumes: redis_data: 健康检查配置详解healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 10s # 检查间隔 timeout: 5s # 超时时间 retries: 3 # 重试次数 start_period: 30s # 启动等待时间 start_period 给容器启动的时间，这段时间内的失败不算在 retries 里。网络配置services: web: build: . networks: - app-network redis: image: redis:7-alpine networks: - app-network networks: app-network: driver: bridge 同一个网络里的容器可以用服务名互相访问，比如 redis:6379。常用命令# 启动所有服务 docker-compose up -d # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs -f web # 重建并启动 docker-compose up -d --build # 停止并清理 docker-compose down # 停止并清理数据卷 docker-compose down -v 踩坑总结 depends_on 只保证容器启动顺序，不保证服务就绪 用 healthcheck + condition: service_healthy 等待服务健康 start_period 给容器启动的时间，避免误判 同一个网络里的容器可以用服务名互相访问 生产环境用 docker-compose up -d --build 重建镜像 从"容器启动了但服务没就绪"到"服务健康后再启动依赖"，只需要配置 healthcheck + condition。坑在于：很多人只用 depends_on，不知道还有 condition 这个选项。