spring-boot 无法在 docker 中启动

Posted

技术标签:

【中文标题】spring-boot 无法在 docker 中启动【英文标题】:spring-boot cannot start in docker 【发布时间】:2016-10-24 21:54:27 【问题描述】:

我在 docker 中运行我的 Spring Boot 应用程序时遇到了一点问题。

堆栈:maven 3+,spring boot(jpa/rest/jetty) - mysql - 在 docker 中部署

所以,我的 pom 文件中有

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.0.M3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <!-- SPRING BOOT DEPENDENCIES -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- add for exlude tomcat -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <!-- END SPRING BOOT DEPENDENCIES-->
    <!-- Jetty (tomcat replacement) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jetty</artifactId>
    </dependency>
    <!-- mysql connector -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- optional dependency javax.el -->
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>3.0.0</version>
    </dependency>
    <!-- google http client -->
    <dependency>
        <groupId>com.google.http-client</groupId>
        <artifactId>google-http-client</artifactId>
        <version>1.21.0</version>
    </dependency>
    <!-- google http jackson -->
    <dependency>
        <groupId>com.google.http-client</groupId>
        <artifactId>google-http-client-jackson2</artifactId>
        <version>1.21.0</version>
    </dependency>
</dependencies>

环境: Ubuntu 16.04 x64 问题: 本地:我尝试在终端中使用以下命令运行我的应用程序

user$ java -Xmx768m -jar /mnf-backend.jar --spring.datasource.url=jdbc:mysql://$MYSQL_PORT_3306_TCP_ADDR/app_1?autoReconnect=true&useSSL=false
user$ #<--- LOOK AT THIS jvm has return of control with 1 status (or same status but not negative)
 :: Spring Boot ::             (v1.4.0.M3) # <--- spring boot starts by itself. HOW????

这不好,我可以忍受。但不是码头工人。 当上面的命令将在 docker 中运行时, docker stop 容器(因为 -> 应用程序退出状态为 1)

ENTRYPOINT ["java", "-Xmx768m", "-jar", "/mnf-backend.jar", "--spring.datasource.url=jdbc:mysql://$MYSQL_PORT_3306_TCP_ADDR/app_1?autoReconnect=true&useSSL=false"]

Docker 将在 1 秒后启动容器并立即停止容器,因为 java 返回控制权。 我寻找允许我配置 spring 应用程序以获得可预测行为或任何想法如何改进我的 docker 指令的方法。 我的 dockerfile 内容:

FROM frolvlad/alpine-oraclejdk8:slim

ENV MNFB_ENV production
ENV SERVER_PORT 9000

ADD ./builds/mnf-latest.jar mnf-backend.jar

EXPOSE 9000



ENTRYPOINT ["java", "-Xmx768m", "-jar", "/mnf-backend.jar", "--spring.datasource.url=jdbc:mysql://$MYSQL_PORT_3306_TCP_ADDR/minifinance?autoReconnect=true&useSSL=false"]

容器的docker日志

例如:当我启动 nodejs 应用程序控件时,直到应用程序未完成才返回

user$ node ./server.js
[...here program output and stdout strings]
[... it may be stopped by ctrl+c for example]

【问题讨论】:

您可以发布您使用的 Dockerfile 吗?还有,有什么不好是你能容忍的? 对不起我的英语。我的意思是我可以在本地容忍这种弹簧行为,但不能在 docker 中容忍 如果应用程序 (java) 以错误代码 1 退出 - 这意味着您在环境中存在一些问题,而不是 Spring Boot。查找 docker 容器 ID 或名称,并使用docker logs &lt;container-id&gt; 找出问题所在。 在容器停止之前,您是否收到任何错误消息?如果没有,您可以发布docker logs &lt;container-id&gt; 输出吗? 日志丢失 :( 日志输出中没有任何字符串。见上面的截图 【参考方案1】:

我认为问题在于命令行中的 & 符号:

--spring.datasource.url=jdbc:mysql://$MYSQL_PORT_3306_TCP_ADDR/app_1?autoReconnect=true&amp;useSSL=false"]

尝试逃避它:

--spring.datasource.url=jdbc:mysql://$MYSQL_PORT_3306_TCP_ADDR/app_1?autoReconnect=true\&amp;useSSL=false"]

& 符号表示在后台启动进程的 shell。这正是您的本地机器上发生的事情。如果你启动你的 jar,进程应该在前台启动......并且提示不应该直接返回。

【讨论】:

【参考方案2】:

为了保持简单和干净,我们在 database.properties 中添加了数据库属性

mongo db 数据库配置

spring.data.mongodb.database=abc-auth
spring.data.mongodb.host=192.168.2.2
spring.data.mongodb.port=27017
spring.data.mongodb.password=abc234quth
spring.data.mongodb.username=abc-auth

我们在运行 Docker 时推送此文件,因此只有数据库属性会被现有的 application.properties 覆盖

ENTRYPOINT ["java","-jar","/home/docker/service/abc.jar","--spring.config.location=application.properties"]

【讨论】:

以上是关于spring-boot 无法在 docker 中启动的主要内容,如果未能解决你的问题,请参考以下文章

无法将docker Spring-Boot应用程序与docker-compose中的mysql容器和flyway连接起来

如何将 Spring-Boot Web 服务转换为 Docker 映像?

无法将 spring-boot 2 服务连接到不同容器中的 mysql

spring-boot项目的docker集成化部署

改进 Docker 中的 Spring-Boot 启动

在 docker 容器中重新部署 spring-boot 应用程序?