【问题标题】:With docker-compose, database container is not up and running使用 docker-compose,数据库容器未启动并运行
【发布时间】:2019-11-13 03:11:02
【问题描述】:

我正在关注this tutorial 使用 docker-compose 设置 Spring Boot 项目。这是我所做的:

我的 application.properties:

spring.datasource.url = jdbc:mysql://mysql-demo-container:3306/demo_db?useSSL=false
spring.datasource.username = root
spring.datasource.password =root

spring.datasource.tomcat.testWhileIdle = true
spring.datasource.tomcat.timeBetweenEvictionRunsMillis = 60000
spring.datasource.tomcat.validationQuery = SELECT 1


spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

我的Dockerfile

`FROM java:8
LABEL maintainer=“foo.bar@gmail.com”
VOLUME /tmp
EXPOSE 8080
ADD target/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar"]`

我有这个docker-compose.yml

version: '3'

services:
  mysql-demo-container:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root
      - MYSQL_DATABASE=demo_db
      - MYSQL_PASSWORD=myPass
    ports:
      - 2012:3306
    volumes:
      - /data/mysql


  spring-boot-jpa-app:
    image: spring-boot-jpa-image
    build:
      context: ./
      dockerfile: Dockerfile
    depends_on:
      - mysql-demo-container
    ports:
      - 8087:8080
    volumes:
      - /data/spring-boot-app

我首先 mvn clean install 构建项目 jar 文件,然后运行 ​​docker-compose up 构建图像并希望运行容器。

日志:

$ docker-compose up
    Creating network "spring-boot-data-jpa-example-master_default" with the default driver
    Creating spring-boot-data-jpa-example-master_mysql-demo-container_1 ... done
    Creating spring-boot-data-jpa-example-master_spring-boot-jpa-app_1  ... done
    Attaching to spring-boot-data-jpa-example-master_mysql-demo-container_1, spring-boot-data-jpa-example-master_spring-boot-jpa-app_1
    mysql-demo-container_1  | Initializing database
    mysql-demo-container_1  | 2019-07-02T13:03:05.097872Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
    mysql-demo-container_1  | 2019-07-02T13:03:05.098037Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server in progress as process 29
    mysql-demo-container_1  | 2019-07-02T13:03:09.171833Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
    spring-boot-jpa-app_1   | 
    spring-boot-jpa-app_1   |   .   ____          _            __ _ _
    spring-boot-jpa-app_1   |  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    spring-boot-jpa-app_1   | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    spring-boot-jpa-app_1   |  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    spring-boot-jpa-app_1   |   '  |____| .__|_| |_|_| |_\__, | / / / /
    spring-boot-jpa-app_1   |  =========|_|==============|___/=/_/_/_/
    spring-boot-jpa-app_1   |  :: Spring Boot ::        (v1.5.9.RELEASE)
    spring-boot-jpa-app_1   | 
    spring-boot-jpa-app_1   | 2019-07-02 13:03:11.516  INFO 1 --- [           main] .s.e.SpringBootDataJpaExampleApplication : Starting SpringBootDataJpaExampleApplication v0.0.1-SNAPSHOT on 3c0d94b76fd6 with PID 1 (/spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar started by root in /)
    spring-boot-jpa-app_1   | 2019-07-02 13:03:11.556  INFO 1 --- [           main] .s.e.SpringBootDataJpaExampleApplication : No active profile set, falling back to default profiles: default
    spring-boot-jpa-app_1   | 2019-07-02 13:03:11.979  INFO 1 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6d5380c2: startup date [Tue Jul 02 13:03:11 UTC 2019]; root of context hierarchy
    mysql-demo-container_1  | 2019-07-02T13:03:13.525348Z 0 [System] [MY-013170] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server has completed
    mysql-demo-container_1  | Database initialized
    mysql-demo-container_1  | MySQL init process in progress...
    mysql-demo-container_1  | MySQL init process in progress...
    mysql-demo-container_1  | MySQL init process in progress...
    mysql-demo-container_1  | 2019-07-02T13:03:15.636380Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release.
    mysql-demo-container_1  | 2019-07-02T13:03:15.636539Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting as process 80
    mysql-demo-container_1  | 2019-07-02T13:03:18.070695Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
    mysql-demo-container_1  | 2019-07-02T13:03:18.081045Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
    mysql-demo-container_1  | 2019-07-02T13:03:18.152808Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.16'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server - GPL.
    mysql-demo-container_1  | 2019-07-02T13:03:18.311442Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock'
    spring-boot-jpa-app_1   | 2019-07-02 13:03:20.039  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
    spring-boot-jpa-app_1   | 2019-07-02 13:03:20.221  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    spring-boot-jpa-app_1   | 2019-07-02 13:03:20.232  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.23
    spring-boot-jpa-app_1   | 2019-07-02 13:03:21.210  INFO 1 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    spring-boot-jpa-app_1   | 2019-07-02 13:03:21.213  INFO 1 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 9251 ms
    spring-boot-jpa-app_1   | 2019-07-02 13:03:22.153  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
    spring-boot-jpa-app_1   | 2019-07-02 13:03:22.169  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
    spring-boot-jpa-app_1   | 2019-07-02 13:03:22.178  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
    spring-boot-jpa-app_1   | 2019-07-02 13:03:22.178  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
    spring-boot-jpa-app_1   | 2019-07-02 13:03:22.181  INFO 1 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
    mysql-demo-container_1  | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
    mysql-demo-container_1  | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
    spring-boot-jpa-app_1   | 2019-07-02 13:03:25.161 ERROR 1 --- [           main] o.a.tomcat.jdbc.pool.ConnectionPool      : Unable to create initial connections of pool.
    spring-boot-jpa-app_1   | 
    spring-boot-jpa-app_1   | com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
    spring-boot-jpa-app_1   | 
    spring-boot-jpa-app_1   | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    spring-boot-jpa-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:989) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:341) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2189) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2222) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2017) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:779) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_111]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.Util.handleNewInstance(Util.java:425) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:389) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:330) ~[mysql-connector-java-5.1.44.jar!/:5.1.44]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.PooledConnection.connectUsingDriver(PooledConnection.java:310) ~[tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.PooledConnection.connect(PooledConnection.java:203) ~[tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.ConnectionPool.createConnection(ConnectionPool.java:735) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.ConnectionPool.borrowConnection(ConnectionPool.java:667) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.ConnectionPool.init(ConnectionPool.java:482) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.ConnectionPool.<init>(ConnectionPool.java:154) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.DataSourceProxy.pCreatePool(DataSourceProxy.java:118) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.DataSourceProxy.createPool(DataSourceProxy.java:107) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.apache.tomcat.jdbc.pool.DataSourceProxy.getConnection(DataSourceProxy.java:131) [tomcat-jdbc-8.5.23.jar!/:na]
    spring-boot-jpa-app_1   |   at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:111) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
    spring-boot-jpa-app_1   |   at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:77) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
    spring-boot-jpa-app_1   |   at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:326) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
    spring-boot-jpa-app_1   |   at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366) [spring-jdbc-4.3.13.RELEASE.jar!/:4.3.13.RELEASE]
    spring-boot-jpa-app_1   |   at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.getDatabase(DatabaseLookup.java:72) [spring-boot-autoconfigure-1.5.9.RELEASE.jar!/:1.5.9.RELEASE]
    spring-boot-jpa-app_1   |   at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:139) [spring-boot-autoconfigure-1.5.9.

从日志开头可以看出,容器似乎已成功创建。

运行docker ps 显示我:

docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                PORTS                                                      NAMES
8fa64acb363d        mysql:latest                    "docker-entrypoint.s…"   30 minutes ago      Up 30 minutes         33060/tcp, 0.0.0.0:2012->3306/tcp                          spring-boot-data-jpa-example-master_mysql-demo-container_1

错误的原因可能是什么?

【问题讨论】:

  • 您没有显示日志的相关部分,因为没有迹象表明 MySQL 容器无法运行。事实上,我会假设所发生的事情正好相反。您的应用程序容器不会等到 MySQL 准备好接受连接,所以我假设您的应用程序会在 CommunicationsException 发生时停止。请注意,depends_on 并不能保证您的容器已准备就绪。
  • 我更新了错误部分。我希望现在人们可以取消投票。
  • 感谢您的日志。但是,这是您的应用程序容器的错误。您告诉我们应用程序容器仍在运行,但数据库容器没有。这意味着如果您发布数据库容器的日志会更有帮助。你能告诉我们docker ps的输出吗?
  • @Ntwobike 从application.properties 你可以弥补他/她正在使用root:root
  • @Leem 谢谢!你能告诉我们docker ps的输出吗?现在的日志只是让它看起来好像应用程序容器没有运行,而数据库容器正在运行。

标签: mysql spring-boot docker docker-compose


【解决方案1】:

您应该注意reference documentation of Docker Compose 中的这个非常重要的脚注:

depends_on 在启动 web 之前不会等待 dbredis “准备好” - 仅在它们启动之前。如果您需要等待服务就绪,请参阅Controlling startup order 了解有关此问题的更多信息和解决策略。

在您的情况下,您的 Spring 引导容器会在您的 MySQL 容器启动后立即启动。虽然不能保证 MySQL 在 Spring boot 设置其连接池时能够进行连接。

这意味着你的 Spring boot 连接将无法启动,因为 MySQL 还没有准备好。这会导致您的应用程序容器被杀死。


the documentation I quoted 中提到了此问题的解决方案。也就是说,您必须使用某种轮询机制来查看您是否可以连接到您的数据库。

如果您不想使用wait-for-itwait-for 之类的工具,您可以编写一个简单的Shell 脚本来执行以下操作:

while ! exec 6<>/dev/tcp/mysql-demo-container/3306; do
    echo "Trying to connect to MySQL..."
    sleep 10
done

exec java -jar spring-boot-data-jpa-example-0.0.1-SNAPSHOT.jar

这也意味着您必须更改 Dockerfile 中的 ENTRYPOINT 以引用此类 shell 脚本,而不是直接运行您的 JAR 文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2018-05-16
    • 1970-01-01
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多