You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Docker服务等待LocalStack SQS队列创建完成后启动?

解决Docker Compose中业务服务提前启动(早于SQS队列创建)的问题

我正在编写docker-compose.yml,用来同时运行LocalStack(提供SQS服务)、MySQL数据库和2个业务服务。现在遇到的问题是,业务服务会在SQS队列创建完成前就启动,不符合预期。试过健康检查但没效果,想知道能不能让业务服务先休眠等待队列创建好。附上我的docker-compose文件:

version: "3.8"
services:

localstack:
        container_name: "DGT-localstack_main"
        image: localstack/localstack
        ports:
          - "4566:4566"            # LocalStack Gateway
          - "4510-4559:4510-4559"  # external services port range
          - "53:53"                # DNS config (only required for Pro)
          - "53:53/udp"            # DNS config (only required for Pro)
          - "443:443"              # LocalStack HTTPS Gateway (only required for Pro)
        environment:
          - DEBUG=${DEBUG-}
          - PERSISTENCE=${PERSISTENCE-}
          - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
          - LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-}  # only required for Pro
          - DOCKER_HOST=unix:///var/run/docker.sock
        volumes:
          - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
          - "/var/run/docker.sock:/var/run/docker.sock"
        networks:
          - localstack_network

awslocal_cli:
        image: amazon/aws-cli
        depends_on: 
          - localstack
        entrypoint: /bin/sh -c
        networks:
          - localstack_network
        command: >  
          '
            echo "########### Creating profile ###########"
    
            aws configure set aws_access_key_id ignore
            aws configure set aws_secret_access_key ignore
            aws configure set region eu-north-1
    
            echo "########### Creating SQS ###########"
            aws sqs create-queue --endpoint-url=http://localstack:4566 --queue-name=FIRST_QUEUE
            aws sqs create-queue --endpoint-url=http://localstack:4566 --queue-name=SECOND_QUEUE
            
    
            echo "########### Listing SQS ###########"
            aws sqs list-queues --endpoint-url=http://localstack:4566
           '

db:
        container_name: db
        image: mysql:8.0.28
        command: --lower_case_table_names=1
        ports:
          - "3308:3306"
        environment:
          - MYSQL_ROOT_PASSWORD=root
          - MYSQL_DATABASE=maindb
        volumes:
        - ./db_config/core/data:/var/lib/mysql
        networks:
          - localhost_network

api:
    container_name: Api
    image: api:1.0
    build:
      context: blabla
      dockerfile: blabla
    ports:
      - blabla
    env_file: ./Server/common.env
    environment:
      - blabla
    restart: on-failure 
    depends_on:
      - core
    networks:
      - localhost_network

core:
        container_name: Core
        image: core:1.0
        build:
          context: blabla
          dockerfile: blabla
        ports:
          - "5115:80"
        env_file: .blabla
        environment:
          - blabla
        restart: on-failure 
        depends_on:
          - localstack
          - awslocal_cli
          - db
        networks:
          - localstack_network
          - localhost_network

networks:
      localstack_network:
      localhost_network:

可行解决方案

方法1:给队列创建任务添加健康检查,让业务服务依赖健康状态

之前的健康检查没效果,大概率是没配置到点上。我们可以给LocalStack和awslocal_cli分别配置健康检查,确保LocalStack服务就绪、队列创建完成后,再启动业务服务。

修改后的完整docker-compose配置:

version: "3.8"
services:
  localstack:
    container_name: "DGT-localstack_main"
    image: localstack/localstack
    ports:
      - "4566:4566"            # LocalStack Gateway
      - "4510-4559:4510-4559"  # external services port range
      - "53:53"                # DNS config (only required for Pro)
      - "53:53/udp"            # DNS config (only required for Pro)
      - "443:443"              # LocalStack HTTPS Gateway (only required for Pro)
    environment:
      - DEBUG=${DEBUG-}
      - PERSISTENCE=${PERSISTENCE-}
      - LAMBDA_EXECUTOR=${LAMBDA_EXECUTOR-}
      - LOCALSTACK_API_KEY=${LOCALSTACK_API_KEY-}  # only required for Pro
      - DOCKER_HOST=unix:///var/run/docker.sock
    volumes:
      - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      - localstack_network
    # LocalStack健康检查:验证SQS服务是否就绪
    healthcheck:
      test: ["CMD", "awslocal", "sqs", "list-queues"]
      interval: 5s
      timeout: 10s
      retries: 10
      start_period: 20s

  awslocal_cli:
    image: amazon/aws-cli
    # 等待LocalStack健康就绪后再执行队列创建
    depends_on: 
      localstack:
        condition: service_healthy
    entrypoint: /bin/sh -c
    networks:
      - localstack_network
    command: >  
      '
        echo "########### Creating profile ###########"

        aws configure set aws_access_key_id ignore
        aws configure set aws_secret_access_key ignore
        aws configure set region eu-north-1

        echo "########### Creating SQS ###########"
        aws sqs create-queue --endpoint-url=http://localstack:4566 --queue-name=FIRST_QUEUE
        aws sqs create-queue --endpoint-url=http://localstack:4566 --queue-name=SECOND_QUEUE

        echo "########### Listing SQS ###########"
        aws sqs list-queues --endpoint-url=http://localstack:4566
      '
    # 验证队列是否创建成功
    healthcheck:
      test: ["CMD", "aws", "sqs", "get-queue-url", "--endpoint-url=http://localstack:4566", "--queue-name", "FIRST_QUEUE"]
      interval: 2s
      timeout: 5s
      retries: 5

  db:
    container_name: db
    image: mysql:8.0.28
    command: --lower_case_table_names=1
    ports:
      - "3308:3306"
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=maindb
    volumes:
      - ./db_config/core/data:/var/lib/mysql
    networks:
      - localhost_network
    # MySQL健康检查:验证数据库是否就绪
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
      interval: 5s
      timeout: 10s
      retries: 10
      start_period: 20s

  api:
    container_name: Api
    image: api:1.0
    build:
      context: blabla
      dockerfile: blabla
    ports:
      - blabla
    env_file: ./Server/common.env
    environment:
      - blabla
    restart: on-failure 
    depends_on:
      core:
        condition: service_started
    networks:
      - localhost_network

  core:
    container_name: Core
    image: core:1.0
    build:
      context: blabla
      dockerfile: blabla
    ports:
      - "5115:80"
    env_file: .blabla
    environment:
      - blabla
    restart: on-failure 
    # 等待所有依赖服务健康就绪后再启动
    depends_on:
      localstack:
        condition: service_healthy
      awslocal_cli:
        condition: service_healthy
      db:
        condition: service_healthy
    networks:
      - localstack_network
      - localhost_network

networks:
  localstack_network:
  localhost_network:

方法2:在业务服务启动前添加等待脚本

如果不想修改太多健康检查配置,可以直接在业务服务的启动流程里加入队列检查逻辑。比如修改core服务的entrypoint:

core:
  # ...其他配置不变
  entrypoint: /bin/sh -c '
    until aws sqs get-queue-url --endpoint-url=http://localstack:4566 --queue-name FIRST_QUEUE >/dev/null 2>&1 && aws sqs get-queue-url --endpoint-url=http://localstack:4566 --queue-name SECOND_QUEUE >/dev/null 2>&1; do
      echo "Waiting for SQS queues to be created..."
      sleep 2
    done
    exec your-original-entrypoint-command
  '

注意:需要确保业务服务容器内安装了aws-cli,或者把检查逻辑封装到启动脚本里。


关键注意点

  • depends_on默认只等待容器启动,不等待容器内的命令执行完成,必须通过condition: service_healthy来绑定健康状态
  • 保留restart: on-failure可以应对偶尔的网络波动导致的启动失败
  • 确保服务所在的网络互通,比如core同时加入两个网络,能正常访问LocalStack和MySQL

内容的提问来源于stack exchange,提问作者ene.andrei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:45:13