如何让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
相关产品推荐
相关产品推荐

