You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Docker Compose构建镜像后,Spring Boot与Cassandra无法协同启动如何解决?

问题分析与解决方案

首先咱们得理清楚为什么docker run只启动了Spring Boot容器,没拉起Cassandra:

docker run单个容器的启动命令,它完全不知道你在docker-compose.yaml里定义的多服务依赖、专属网络、环境变量关联这些配置逻辑。你虽然拉取了两个镜像,但单独运行Spring Boot容器时,Cassandra容器根本没被启动;就算你手动启动了Cassandra,两个容器也不在同一个可互相发现的网络里,Spring Boot自然找不到Cassandra服务。

另外我注意到你的docker-compose.yaml还有个小疏漏:cassandra服务没有指定image字段,这会导致docker-compose push只推送Spring Boot的镜像,Cassandra的镜像其实没被推送到Docker Hub——你说拉取后显示Cassandra已下载,大概率是目标机器本地有同名镜像,或者你手动推送过,但规范做法是给每个需要推送的服务都加上image字段。

下面是具体的解决步骤:

一、推荐做法:继续用docker-compose启动(最省心)

既然你的项目是多服务架构,docker-compose本来就是为管理这种场景设计的,直接在目标机器上这么操作:

  1. 先修改你的docker-compose.yaml,给cassandra服务加上image字段,确保它能被推送和拉取:

    version: '3'
    services:
      cassandra:
        build:
          context: ../
          dockerfile: docker/cassandra/Dockerfile
        image: myrepo/cassandra  # 新增这行,指定镜像仓库路径
        ports:
          - "9042:9042"
        container_name: cassandra
      spring-boot-cassandra:
        build:
          context: ../
          dockerfile: docker/springbootsample/Dockerfile
        links:
          - cassandra
        ports:
          - "8080:8080"
        environment:
          SPRING_DATA_CASSANDRA_CONTACT_POINTS: cassandra
        container_name: springboot
        entrypoint: /wait-for-it.sh cassandra:9042 -- java -Djava.security.egd=file:/dev/./urandom -jar app.jar
        depends_on:
          - "cassandra"
        image: myrepo/springbootsample
    networks:
      default:
        driver: bridge
    
  2. 在本地重新构建并推送两个镜像:

    docker-compose build
    docker-compose push
    
  3. 在目标机器上拉取并启动所有服务:

    docker-compose pull
    docker-compose up -d  # -d 参数让容器后台运行
    

    这样docker-compose会自动帮你创建专属网络、启动Cassandra、通过wait-for-it.sh等待它就绪后再启动Spring Boot,完全遵循你定义的依赖关系。

二、如果非要用docker run手动启动(不推荐,需手动处理所有依赖)

如果因为特殊原因必须用docker run,你需要手动处理网络、依赖和环境变量:

  1. 先创建一个专属网络,让两个容器能通过服务名互相发现:

    docker network create my-app-network
    
  2. 启动Cassandra容器(确保镜像已推送至Docker Hub或目标机器本地存在):

    docker run -d --name cassandra --network my-app-network -p 9042:9042 myrepo/cassandra
    
  3. 可以通过docker logs cassandra查看日志,直到出现Ready for CQL connections,或者直接启动Spring Boot容器(你的wait-for-it.sh会自动等待Cassandra就绪):

    docker run -d --name springboot --network my-app-network -p 8080:8080 -e SPRING_DATA_CASSANDRA_CONTACT_POINTS=cassandra myrepo/springbootsample
    

额外注意点

  • depends_on只是保证Cassandra容器先启动,不保证它服务就绪,你的wait-for-it.sh配置是正确的,这能确保Spring Boot在Cassandra可连接后才启动。
  • links是Docker的旧特性,docker-compose的默认网络已经支持服务名解析,这个字段可以去掉,不会影响服务发现。

内容的提问来源于stack exchange,提问作者adrianmalz

火山引擎 最新活动